当前位置: 首页 > news >正文

很多大公司为什么禁止在SpringBoot项目中使用Tomcat?

很多大公司为什么“禁止”在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无缝集成。

实际测试数据对比(相同硬件、模拟高并发请求):

指标TomcatUndertowJetty备注
吞吐量 (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更适合现代大厂场景。

如果你在公司遇到这个规范,恭喜你——这是个好习惯,能让你项目更扛打~有具体压测数据或经历,欢迎分享!😂

http://www.cnnetsun.cn/news/53509.html

相关文章:

  • conda使用详细指南
  • 豆包与DeepSeek底层大模型的深度解析:技术架构、设计理念与生态分野
  • Linux系统中的socket激活:先创建监听端口,后启动程序
  • 从零解决pyproject.toml构建失败的实战指南
  • Redis Lua脚本入门:从零写出你的第一个原子操作
  • 旧机转手不再慌!电子产品信息清除新国标落地,核心技术逻辑全解析
  • 安全体验馆好用供应商
  • 第二章——数据分析场景之Python数据可视化:用Matplotlib与Seaborn绘制洞察之图
  • 【Java毕设全套源码+文档】基于springboot的高校毕业生离校管理系统小程序设计与实现(丰富项目+远程调试+讲解+定制)
  • 如何用AI工具jstat优化Java应用性能分析
  • 【Java毕设全套源码+文档】基于springboot的高校毕业生信息管理系统的设计与实现(丰富项目+远程调试+讲解+定制)
  • Day 38 GPU训练及类的call方法
  • 【Python实战】火爆全网的“隔空手势画板”是如何实现的?教你用OpenCV+MediaPipe复刻钢铁侠黑科技!
  • 【学习笔记】如果打造可复现、可评测、可迭代的AI技术体系
  • 【论文自动阅读】See Once, Then Act: Vision-Language-Action Model with Task Learning from One-Shot Video Demo
  • 利用齐次坐标系证明各种几何定理【射影几何】
  • 小程序基于springboot的乡镇普法知识科普宣传系统 律师预约系统设计与实现_qf4cwws6(java毕业设计项目源码)
  • 面向对象编程三大特性:封装、继承、多态的核心要义
  • leetcode 2147. 分隔长廊的方案数 困难
  • 学生党必备!这款桌面课表工具太省心了
  • 深度学习实验14代码
  • 优化及性能-–-behaviac
  • 练题100天——DAY26:汇总区间+丢失的数字+数组交集
  • 当AI芯片不再性感:博通的高增长,为何成了催命符?
  • Vibe Coding:AI驱动的编程新范式
  • AI 数字孪生工厂:西门子与中信特钢的实践,如何降本 11%?
  • Spring IoC的实现机制是什么?
  • 耐用折叠屏手机推荐:三星Galaxy Z TriFold如何破解“折痕与耐用”难题?
  • 前端技术风险防控:以防为主,防控结合
  • 给女神发“在吗”,她回了个表情包是几个意思?—— 硬核探讨TCP 三次握手