针对 Tomcat、Jetty、Undertow 的详细对比,并结合 Spring Boot 的实际使用说明
1. 基本概述
特性 | Tomcat | Jetty | Undertow |
---|---|---|---|
开发方 | Apache 基金会 | Eclipse 基金会 | Red Hat(JBoss/WildFly 子项目) |
定位 | 传统 Servlet 容器 | 轻量级嵌入式服务器 | 高性能非阻塞服务器 |
核心协议 | HTTP/1.1, 支持 HTTP/2(需配置) | HTTP/1.1, HTTP/2, WebSocket | HTTP/1.1, HTTP/2, WebSocket |
主要应用场景 | 企业级 Web 应用(如 Spring MVC) | 微服务、嵌入式系统(如 Spring Boot) | 高并发 API、实时通信(如 WebSocket) |
2. 架构与性能
维度 | Tomcat | Jetty | Undertow |
---|---|---|---|
架构模型 | 传统线程池(BIO/NIO可选) | 基于 NIO 的非阻塞模型 | 基于 XNIO 的事件驱动非阻塞模型 |
性能特点 | 高稳定性,中等并发能力 | 高并发处理,低延迟 | 极致性能,高吞吐量,低内存占用 |
资源消耗 | 较高(默认配置较保守) | 较低(轻量级设计) | 极低(优化内存管理) |
典型性能场景 | 500-1000 并发(默认配置) | 5000-10000 并发连接 | 10000+ 并发连接 |
3. 功能与生态
功能 | Tomcat | Jetty | Undertow |
---|---|---|---|
Servlet 支持 | 完整支持(Servlet 6.0+) | 完整支持(Servlet 6.0+) | 完整支持(Servlet 6.0+) |
HTTP/2 | 需手动配置(ALPN 支持复杂) | 原生支持 | 原生支持 |
WebSocket | 支持(需额外配置) | 原生支持 | 原生支持 |
模块化设计 | 无(功能集中) | 支持(按需加载模块) | 轻量级核心(扩展性强) |
嵌入式部署 | 支持(但较重) | 极佳(Spring Boot 默认替代选项) | 极佳(Spring Boot 可选集成) |
4. 配置与易用性
维度 | Tomcat | Jetty | Undertow |
---|---|---|---|
配置方式 | XML 文件,图形化管理工具(如 Manager) | 代码/XML,强调 API 配置 | 代码/编程式配置(灵活性高) |
学习曲线 | 低(文档丰富,社区成熟) | 中(需理解 NIO 模型) | 较高(需熟悉 XNIO 事件模型) |
默认优化 | 保守(适合传统应用) | 较激进(适合现代架构) | 高度优化(性能优先) |
日志管理 | 完善(与 Log4j 等集成) | 灵活(可定制日志组件) | 简洁(需手动配置扩展) |
5. 核心对比
维度 | Tomcat | Jetty | Undertow |
---|---|---|---|
Spring Boot 默认支持 | ✅ 默认嵌入式容器(spring-boot-starter-web ) | ❌ 需手动配置(替换 Tomcat) | ❌ 需手动配置(替换 Tomcat) |
启动速度 | 中等 | 较快 | 极快 |
内存占用 | 较高 | 较低 | 最低 |
并发能力 | 中等(BIO/NIO 模型) | 高(NIO 非阻塞) | 极高(XNIO 事件驱动) |
适用场景 | 传统 Web 应用、JSP 项目 | 微服务、嵌入式设备 | 高并发 API、WebSocket 实时通信 |
6. 适用场景建议
-
选择 Tomcat:
- 需要稳定性和广泛兼容性的传统企业应用。
- 使用 JSP 或旧版 Java EE 技术的项目。
- 对运维友好,需要图形化管理工具的场景。
-
选择 Jetty:
- 微服务架构或嵌入式应用(如 IoT 设备)。
- Spring Boot 项目希望替换默认容器以降低资源消耗。
- 需要快速启动和低内存占用的场景。
-
选择 Undertow:
- 高并发 API 服务或实时通信(如 WebSocket 聊天室)。
- 对性能极致追求,需低延迟和高吞吐量的系统。
- 与 WildFly 或其他 Red Hat 技术栈集成。
7. 性能对比数据参考
- 内存占用(空载):
- Tomcat: ~120MB
- Jetty: ~50MB
- Undertow: ~30MB
- 响应时间(10k 并发):
- Tomcat: ~200ms
- Jetty: ~150ms
- Undertow: ~100ms
- 吞吐量(QPS):
- Tomcat: 5k-8k
- Jetty: 10k-15k
- Undertow: 20k-30k+
8. 在 Spring Boot 中使用
(1) Tomcat(默认容器)
-
依赖配置:无需额外配置,
spring-boot-starter-web
默认包含 Tomcat。<!-- Maven --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependency>
-
自定义配置:
# application.yml server:port: 8080tomcat:max-threads: 200 # 最大线程数(默认 200)min-spare-threads: 10 # 最小空闲线程数connection-timeout: 5000
(2) Jetty
-
依赖配置:需排除 Tomcat 并添加 Jetty 依赖。
<!-- Maven --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId></exclusion></exclusions> </dependency> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jetty</artifactId> </dependency>
-
自定义配置:
# application.yml server:port: 8080jetty:thread-pool:max-threads: 500 # Jetty 默认线程池配置min-threads: 10
(3) Undertow
-
依赖配置:排除 Tomcat 并添加 Undertow 依赖。
<!-- Maven --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId></exclusion></exclusions> </dependency> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-undertow</artifactId> </dependency>
-
自定义配置:
# application.yml server:port: 8080undertow:threads:io: 4 # I/O 线程数(默认 CPU 核心数 * 2)worker: 40 # 工作线程数(默认 io * 8)buffer-size: 1024 # 缓冲区大小(字节)
9. 性能调优建议
Tomcat
- 优化线程池:调整
max-threads
和min-spare-threads
。 - 开启 NIO 模式(默认已启用):
server:tomcat:protocol: org.apache.coyote.http11.Http11NioProtocol
Jetty
- 异步处理:利用 Jetty 的异步 Servlet 特性提升吞吐量。
- 调整 Selector 线程:
@Bean public JettyServletWebServerFactory jettyServletWebServerFactory() {JettyServletWebServerFactory factory = new JettyServletWebServerFactory();factory.addServerCustomizers(server -> {QueuedThreadPool threadPool = server.getBean(QueuedThreadPool.class);threadPool.setMaxThreads(500);});return factory; }
Undertow
- 优化 XNIO 工作线程:根据 CPU 核心数动态调整
io
和worker
线程。 - 启用直接内存缓冲:
server:undertow:direct-buffers: true # 使用堆外内存提升性能
10. 适用场景与选择建议
场景 | 推荐容器 | 理由 |
---|---|---|
传统企业应用 | Tomcat | 兼容性强,支持 JSP 和旧版 Java EE 规范。 |
微服务/云原生应用 | Jetty | 轻量级、启动快,适合资源受限的 Docker 容器或 Kubernetes 环境。 |
高并发 API/WebSocket | Undertow | 极致性能,内存占用低,适合实时通信和高吞吐场景(如 IM、游戏服务器)。 |
11. 常见问题
Q1:如何在 Spring Boot 中动态切换容器?
- 通过 Maven/Gradle 的依赖排除和引入实现,无需修改代码。
Q2:Undertow 是否支持 Servlet 3.1+?
- ✅ 完全支持 Servlet 4.0、WebSocket 和 HTTP/2。
Q3:Jetty 和 Undertow 对 WebSocket 的支持?
- 两者均原生支持 WebSocket,无需额外配置。
12. 总结
- Tomcat:适合稳定性优先的传统项目,文档和生态完善。
- Jetty:平衡性能与轻量级,适合微服务和嵌入式场景。
- Undertow:性能王者,适合高并发、实时通信需求、低延迟的现代应用。
选择建议:根据项目需求权衡性能、资源消耗和开发体验。微服务或云原生场景可优先考虑 Jetty 或 Undertow;传统企业应用 Tomcat 仍是稳妥选择。