很多大公司为什么“禁止”在Spring Boot项目中使用Tomcat?
严格来说,不是所有大公司都绝对禁止使用Spring Boot的默认嵌入式Tomcat(它是Spring Boot的默认Web服务器),但在许多互联网大厂(如阿里、腾讯、京东等高并发业务场景),强烈推荐或强制替换为Undertow(有时也用Jetty)。这已成为一种常见的技术规范和最佳实践。原因主要集中在性能、资源消耗和高并发支持上,尤其在微服务时代。
核心原因:Undertow在高并发场景下全面优于Tomcat
Spring Boot默认嵌入Tomcat方便开发,但Tomcat设计较“传统”,在极端高并发下有瓶颈:
- 连接管理弱:Tomcat默认偏向短连接(HTTP/1.1 Keep-Alive需手动优化),高并发时频繁TCP握手/挥手开销大,吞吐量受限。
- 线程模型传统:阻塞IO为主,线程池容易耗尽(默认maxThreads=200),内存占用高。
- 资源消耗大:相同配置下,Tomcat内存和CPU占用更高,不适合容器化/云原生密集部署。
Undertow(Red Hat开源,WildFly默认容器)则专为现代高性能设计:
- 非阻塞IO + 异步支持:内置NIO,处理长连接/持久连接更高效。
- 轻量级:内存占用低(测试显示比Tomcat低20-50%),启动更快。
- 高吞吐:基准测试(wrk/JMeter)中,高并发QPS往往高出Tomcat 20-100%(视场景)。
- 完美支持Servlet/WebSocket/HTTP2:与Spring Boot无缝集成。
实际测试数据对比(相同硬件、模拟高并发请求):
| 指标 | Tomcat | Undertow | Jetty | 备注 |
|---|---|---|---|---|
| 吞吐量 (QPS) | 基准 | +30-100% | +10-50% | Undertow 最强,尤其IO密集 |
| 内存占用 | 高 | 最低 | 中等 | Undertow 适合微服务密集部署 |
| CPU 使用 | 中高 | 低 | 低 | 长连接场景 Undertow 胜出 |
| 启动时间 | 中等 | 最快 | 快 | 云原生友好 |
| 高并发稳定性 | 易线程耗尽 | 优秀(非阻塞) | 好 | Undertow 默认持久连接 |
(数据来源于多个基准测试,如JavaCodeGeeks、51CTO等,实际视业务而异)
大厂为什么强制替换?
- 微服务高并发需求:大厂微服务动辄万级QPS,Tomcat容易成瓶颈。替换Undertow后,系统更稳、成本更低(少开机器)。
- 容器化/K8s部署:嵌入式服务器镜像小、资源占用低是关键,Undertow更轻量。
- 统一规范:公司技术栈标准化,避免团队乱用导致性能不均。代码审查时直接禁Tomcat依赖。
- 不是绝对禁:小项目或低并发场景,Tomcat仍OK。但大厂新项目默认Undertow。
阿里巴巴Java开发手册中未明确禁Tomcat(重点在编码规范),但社区和大厂实践(如阿里内部许多团队)倾向Undertow。
如何替换(超级简单,一分钟搞定)
在pom.xml中排除Tomcat,引入Undertow:
<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>
<!-- 引入 Undertow -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
重启项目,日志显示:Undertow started on port(s) 8080。
Jetty替换类似(starter-jetty),适合长连接/WebSocket场景。
总结建议
- 新项目/高并发:优先Undertow,性能起飞!
- 老项目:如果没瓶颈,Tomcat也稳(生态最成熟)。
- 实际选型:压测你的业务!Tomcat不是“坏”,只是Undertow更适合现代大厂场景。
如果你在公司遇到这个规范,恭喜你——这是个好习惯,能让你项目更扛打~有具体压测数据或经历,欢迎分享!😂