概叙
Java web应用性能分析之【性能点概叙】_java web系统性能需求包括哪些-CSDN博客
Java web应用性能分析之服务端慢和优化概叙_cpu飙高java-CSDN博客
实战:16条SpringBoot服务优化技巧_springboot优化-CSDN博客
Java web应用性能分析之【压测工具ab】_ab压测工具-CSDN博客
Java web应用性能分析之【基准测试】_测试中基准-CSDN博客
科普文:SpringBoot项目禁用Tomcat,并用Undertow替换_springboot tomcat 禁用jsp-CSDN博客
Java web应用性能分析概叙_javaweb系统响应缓慢可能的问题,产生的原因-CSDN博客
对于 servlet 栈应用程序(Java web应用),spring-boot-starter-web 通过包含 spring-boot-starter-tomcat 将 Tomcat 包括在内,但也可以使用 spring-boot-starter-jetty 或 spring-boot-starter-undertow 代替。
这是前面梳理的Spring Boot性能优化点之一,这里我们再详细说说:Spring Boot内嵌服务器选型:Tomcat vs Jetty vs Undertow,先说结论。
Tomcat vs Jetty vs Undertow性能指标
推荐策略:根据业务场景选择,高并发场景优先Undertow,稳定性和兼容性需求选择Tomcat,轻量级或长连接场景选择Jetty 。
Spring Boot 内嵌服务器通过简化部署和配置,显著提升了开发效率。
Tomcat 适合传统应用,Jetty 适合轻量级场景,Undertow 适合高并发需求。
开发者需根据业务特点(如吞吐量、资源限制)选择服务器,并通过配置文件或编程方式优化参数。
-
默认选Tomcat:适合大多数场景,兼容性最好。
-
需要高性能选Undertow:适合微服务、云原生架构。
-
WebSocket/长连接选Jetty:如在线聊天、实时推送。
性能优化建议:
- 高并发场景:优先选择 Undertow,通过异步非阻塞模型减少线程切换开销。
- 资源敏感型场景:使用 Jetty 降低内存占用,或 Undertow 减少 GC 压力。
性能峰值 | 中等 | 中高 | 最高 |
资源开销 | 高 | 低 | 最低 |
适用场景 | 传统业务 | 嵌入式/长连接 | 高并发/实时系统 |
维护成本 | 低(默认集成) | 中等 | 高(需调优) |
Tomcat | 传统Web应用、兼容性要求高 | 中等(每秒 5k~8k 请求) | 500ms+ | 较高(线程池占用大) |
Jetty | 嵌入式系统、长连接(WebSocket) | 中高(每秒 6k~10k 请求) | 400ms-500ms | 较低(轻量级设计) |
Undertow | 高并发、实时系统 、异步非阻塞场景 | 高(每秒 10k+ 请求) | <400ms | 最低(零拷贝技术) |
Tomcat vs Jetty vs Undertow优缺点
Tomcat优势:
- 默认集成于Spring Boot,无需额外配置 。
- 成熟稳定,社区支持广泛,兼容性强 。
Tomcat劣势:
- 线程模型基于阻塞IO,高并发时性能下降明显 。
- 内存占用较高,不适合资源敏感型场景 。
Jetty优势:
- 非阻塞IO模型优化长连接场景(如WebSocket) 。
- 轻量级,启动速度快,适合嵌入式部署 。
Jetty劣势:
- 对Servlet规范支持较弱,复杂业务需额外适配 。
- 压测中吞吐量增长低于Undertow 。
Undertow优势:
- 内存占用低,支持零拷贝技术,减少GC压力 。
- 基于Xnio的异步IO模型,支持高达10万级并发 。
Undertow劣势:
- 配置复杂度较高(需手动优化线程池) 。
- 社区生态弱于Tomcat,问题排查成本略高 。
Spring Boot内嵌服务器配置:Tomcat vs Jetty vs Undertow
什么是内嵌服务器(Embedded Server)?
Spring Boot 内嵌服务器(Embedded Server)是将 Web 服务器(如 Tomcat、Jetty、Undertow)直接集成到应用程序中的技术。开发者通过一个独立 JAR 文件即可启动服务,无需额外部署到外部服务器(如传统 Tomcat 容器)。
- 核心特点:
- 独立运行:无需依赖外部服务器,直接通过 java -jar 启动应用。
- 灵活性:支持多种服务器(Tomcat、Jetty、Undertow)自由切换。
- 简化配置:通过配置文件(如 application.properties)调整服务器参数。
高并发场景(如秒杀、实时通信):Undertow配置
- 优先选择Undertow,其异步非阻塞模型在高并发下响应时间更稳定,且资源消耗最低 。
Maven依赖配置,排除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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
启动参数配置
server:
undertow:
threads:
io: 8 # 8 核 CPU 建议值
worker: 256 # 高阻塞场景保持高位
buffer-size: 1024 # 1MB 缓冲区
direct-buffers: true # 启用堆外内存
max-http-post-size: 100MB # 限制大文件上传
no-request-timeout: 30000 # 空闲连接超时(默认60秒)
io 线程数
- 作用:处理非阻塞的网络 I/O 操作(如请求解析、响应输出),直接影响连接吞吐能力。
- 默认值:CPU核心数 × 2(例如 8 核 CPU 默认 16)。用户设置为 4,可能基于特定硬件环境或性能测试结果调整。
worker 线程数
- 作用:处理阻塞型业务逻辑(如数据库操作、复杂计算),需根据业务阻塞系数调整。
- 推荐值:通常为 io线程数 × 8(默认逻辑)。用户设置为 256,适用于高并发阻塞型场景(如电商秒杀)。
buffer-size
- 作用:单个缓冲区大小,影响内存占用及 I/O 效率。默认值通常为 512 或 1024(KB)。
- 用户设置:1024(1MB)适合处理中小型请求体,若需支持大文件传输(如视频上传),可适当增大。
缓冲区与内存优化
-
堆外内存启用:通过 direct-buffers: true 使用直接内存(堆外),减少 GC 压力。
动态调整缓冲区大小:
-
若平均请求体较小(如 API 接口),可降低至 buffer-size: 512 以节省内存。
-
若需处理大文件,增大缓冲区并设置 max-http-post-size 限制请求体上限:
嵌入式系统、长连接(WebSocket)场景:Jetty配置
Jetty:轻量级设计,适合嵌入式设备或需要 WebSocket 长连接的应用。
Maven依赖配置,排除Tomcat后引入Jetty。
<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>
启动参数配置
通过合理配置 Jetty 的线程池和请求限制参数,可显著提升应用在高并发或大文件场景下的稳定性。关键点:
- 使用 server.jetty.threads.max/min 调整线程池大小。
- 通过 max-http-post-size 控制请求体大小。
- 结合压测工具验证配置合理性。
server:
port: 8080
jetty:
# 请求大小限制
max-http-post-size: 100MB
# 线程池配置
threads:
max: 800 # 根据CPU核心数动态调整 CPU核心数 * 200(4核CPU建议800),但需通过压测验证。
min: 8 # 保持默认值即可,避免频繁创建/销毁线程的开销。
# 连接器配置(可选)
connection-idle-timeout: 30000 # 空闲连接超时时间(毫秒)
threads.max | CPU核心数 * 200 | 避免过高导致线程竞争,过低导致请求堆积 |
threads.idle-timeout | 60000(默认60秒) | 空闲线程回收时间,减少资源占用 |
max-http-post-size | 按需设置(如 100MB) | 防止大文件攻击,同时支持业务需求 |
connection-idle-timeout | 30000(30秒) | 快速释放空闲连接,提升连接复用率 |
传统Web应用场景:Tomcat配置
Tomcat:默认选择,适合传统业务场景,稳定性强但资源消耗较高。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Spring Boot 默认使用Tomcat,只需引入 spring-boot-starter-web。
server:
port: 8080
tomcat:
max-threads: 200
min-spare-threads: 20
connection-timeout: 10000 # 10秒超时
max-connections: 10000
accept-count: 200 # 增加等待队列容量
max-threads | 控制 Tomcat 并发处理请求的最大线程数 | 200 | 200 |
min-spare-threads | 初始化时预创建的线程数,用于应对突发请求 | 10 | 20 |
connection-timeout | 客户端建立连接后未发送数据的超时断开时间 | 20000ms (20秒) | 10000ms |
max-connections | Tomcat 同时处理的最大连接数(含排队请求) | 10000 | 10000 |
accept-count | 当 活跃连接数 > max-threads 时,超出线程处理能力的请求会进入等待队列,队列长度由 accept-count 控制(默认100) | 100 | 200 |
性能调优原则
Tomcat 默认配置与扩展能力
吞吐量 | 单机约 5k~8k QPS(取决于业务逻辑复杂度) | 横向扩展集群 + 负载均衡 |
线程竞争 | 高并发下线程切换可能成为瓶颈 | 使用异步编程(如 CompletableFuture) |
连接管理 | 超过 max-connections 直接拒绝连接 | 结合 Nginx 反向代理缓冲请求 |
注:以上建议需结合实际业务场景和硬件资源调整,避免盲目追求高配置导致资源浪费或系统不稳定 。
评论前必须登录!
注册