Java程序在Tomcat和Jetty之间如何选择服务器?

在 Java Web 应用中,选择 Tomcat 还是 Jetty 通常不是由代码“切换”的,而是由部署环境(容器)决定的。你的 Java 程序本身是“容器无关”的(遵循 Servlet/JSP/Filter 等标准),真正决定运行服务器的是你如何构建和部署应用。

以下是关键要点和选择建议:


✅ 核心原则

  • Java EE / Jakarta EE 规范兼容:只要你的代码符合 Servlet、JSP、WebSocket 等标准(不依赖特定容器的私有 API),它就能在 Tomcat、Jetty、WildFly、Undertow 等容器中无缝运行。
  • 选择权在部署阶段:通过打包成 WAR/JAR 文件后,部署到目标服务器即可;无需修改业务代码。

🔍 如何选择?按场景决策

维度 Tomcat Jetty
成熟度与生态 ⭐⭐⭐⭐⭐
最广泛使用,社区庞大,文档丰富,工具支持完善
⭐⭐⭐⭐
轻量但稳定,Spring Boot 默认嵌入式首选
性能 & 资源占用 较重,适合传统单体应用 更轻量,启动快,内存占用低,适合微服务/云原生
嵌入式集成 需额外配置(如 spring-boot-starter-tomcat) Spring Boot 默认使用 Jetty(可轻松切换为 Tomcat)
高并发连接 优秀,但线程模型较传统 基于 NIO,异步支持更好,适合长连接(WebSocket/SSE)
典型用例 企业级单体应用、遗留系统、需要丰富管理界面 微服务、容器化部署、边缘计算、实时通信应用

🛠️ 实际部署方式对比

1. WAR 包部署(外部容器)

# 编译项目生成 myapp.war
mvn clean package -DskipTests

# 部署到 Tomcat
cp myapp.war $CATALINA_HOME/webapps/

# 或部署到 Jetty
java -jar jetty-runner.jar --port 8080 myapp.war
# 或使用 jetty-maven-plugin
mvn jetty:run-war

2. Spring Boot 嵌入式容器(推荐现代做法)

在 pom.xml 中控制默认容器:

<!-- 默认是 Tomcat -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- 切换到 Jetty -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jetty</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>

运行时只需执行:

java -jar your-app.jar

容器自动内嵌,无需外部安装。


⚠️ 注意事项

  • ❌ 避免使用非标准 API(如 org.apache.catalina.* 或 org.eclipse.jetty.* 内部类),否则将失去可移植性。
  • ✅ 使用标准接口:ServletContext, HttpServletRequest, @WebServlet, @PostConstruct 等。
  • 🔧 若需自定义行为(如 SSL、线程池调优),应在 server.xml(Tomcat)或 jetty.xml / 编程式配置(Jetty)中完成,而非硬编码到 Java 代码。

📌 总结建议

你的需求 推荐选择
传统企业应用、团队熟悉 Tomcat Tomcat
微服务架构、Kubernetes 部署、追求轻量快速启动 Jetty(尤其配合 Spring Boot)
需要大量 WebSocket/长连接 Jetty(NIO 优势明显)
已有现有 Tomcat 基础设施 继续用 Tomcat(迁移成本高)
新起项目,不确定未来扩展 优先选 Spring Boot + 可插拔容器(默认 Jetty/Tomcat 可一键切换)

💡 提示:可通过 java -version + ps aux | grep java 查看当前运行进程使用的容器类型,或通过访问 /manager/html(Tomcat)或 http://host:port/jetty-status(Jetty)确认。

如需具体迁移示例或性能测试方案,欢迎补充你的应用场景!