优化背景
当你的application需要支持瞬时高并发的时候,tomcat已经不在是最优的选择,我们可以改为Undertow,并对其进行优化。
Undertow 是一个轻量级的、高性能的Java Web 服务器,由JBoss 开发并开源。它是基于非阻塞(non-blocking)的I/O模型,具有低资源消耗和高并发处理能力。
SpringBoot3如何从tomcat改为undertow
需要在pom.xml
中排除Tomcat,并添加Undertow的依赖:
XML
<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
或 application.properties
中添加以下配置:
XML
server:
undertow:
# 线程池配置
threads:
# I/O线程数(建议设置为CPU核心数的1-2倍)
io: 16
# 工作线程数(建议设置为CPU核心数的8-16倍)
worker: 256
# 缓冲池配置
buffer-size: 1024
# 是否直接使用内存作为缓冲区
direct-buffers: true
限制接口超时时间
XML
server:
undertow:
# 请求超时设置(毫秒)
no-request-timeout: 30000
# 连接空闲超时(毫秒)
idle-timeout: 60000
限制请求体大小不超过2KB
XML
server:
undertow:
# 限制HTTP POST请求体大小(2KB=2048字节)
max-http-post-size: 2048
请求压缩配置
SpringBoot的server compression 功能用于减少响应数据的大小 ,从而提高传输效率 ,减少带宽占用,加快页面加载速度。它通常使用Gzip 或Deflate等压缩算法来优化HTTP响应。
作用
-
减少数据传输量:压缩后数据体积更小,降低网络开销。
-
提高加载速度:特别适用于前端页面、API接口等场景。
-
降低服务器负载:减少数据传输时间,提高服务器吞吐量。
-
优化用户体验:页面加载更快,提升访问流畅度。
推荐配置
在SpringBoot的application.yml
或application.properties
中启用压缩:
server:
compression:
enabled: true # 开启压缩
min-response-size: 1024 # 触发压缩的最小响应大小(默认2KB)
mime-types: application/json, text/html, text/xml, text/plain, text/css, application/javascript # 需要压缩的内容类型
excluded-user-agents: IE6, IE7 # 排除旧版浏览器
启用HTTP/2 (需要SSL支持)
XML
server:
http2:
enabled: true
Undertow 访问日志配置
XML
server:
undertow:
accesslog:
enabled: true
dir: ./logs
prefix: access_log.
suffix: .log
pattern: '%t %a "%r" %s (%D ms)'
rotate: true
监控与调优建议
-
监控线程池状态:通过JMX或Actuator监控线程池使用情况
-
压力测试:使用JMeter或wrk进行负载测试,观察线程池表现
-
JVM调优:根据负载情况调整JVM堆内存和GC参数
-
连接池调优 :如果使用数据库,确保连接池配置与服务器线程数匹配 (SpringBoot3 + Druid + DynamicDataSource + PgSQL 连接池优化方案-CSDN博客)
附录:Undertow配置属性
Spring Boot 预置了很多属性,可用于在 applicaton.properties | yaml
中对 Undertow 服务器进行个性化配置。
它们都以 server.undertow.*
开头,总结如下:
配置项 | 说明 | 示例 |
---|---|---|
server.undertow.accesslog.dir |
Undertow 访问日志目录。 | |
server.undertow.accesslog.enabled |
是否启用访问日志。 | false |
server.undertow.accesslog.pattern |
访问日志的格式。 | common |
server.undertow.accesslog.prefix |
日志文件前缀。 | access_log. |
server.undertow.accesslog.rotate |
是否开启日志滚动。 | true |
server.undertow.accesslog.suffix |
日志文件后缀。 | log |
server.undertow.always-set-keep-alive |
是否应在所有响应中添加 Connection: keep-alive Header,即使 HTTP 规范没有要求。 |
true |
server.undertow.buffer-size |
每个 buffer 的大小。默认大小是根据 JVM 可用的最大内存确定的。 | |
server.undertow.decode-slash |
是否应解码已编码的斜线字符(%2F )。如果前端代理不执行相同的解码,解码可能会导致安全问题。只有在传统应用程序需要时才启用。设置后,server.undertow.allow-encoded-slash 无效。 |
|
server.undertow.decode-url |
是否对 URL 进行解码。禁用时,URL 中的百分比编码字符将保持原样。 | true |
server.undertow.direct-buffers |
是否在 Java 堆外分配 buffer。默认大小是根据 JVM 可用的最大内存确定的。 | |
server.undertow.eager-filter-init |
是否应在启动时初始化 servlet Filter | true |
server.undertow.max-cookies |
允许的最大 cookie 数量。这一限制是为了防止基于哈希碰撞的 DOS 攻击。 | 200 |
server.undertow.max-headers |
允许的最大 header 数量。这一限制是为了防止基于哈希碰撞的 DOS 攻击。 | |
server.undertow.max-http-post-size |
HTTP post content 的最大大小。当值为-1(默认值)时,大小为无限。 | -1B |
server.undertow.max-parameters |
允许查询或路径参数的最大数量。这一限制是为了防止基于哈希碰撞的 DOS 攻击。 | |
server.undertow.no-request-timeout |
在服务器关闭连接之前,连接在不处理请求的情况下闲置的时间。 | |
server.undertow.options.server.* |
在 io.undertow.UndertowOptions 中定义的服务器选项。 |
|
server.undertow.options.socket.* |
在 org.xnio.Options 中定义的 socket 选项。 |
|
server.undertow.preserve-path-on-forward |
转发请求时是否保留请求路径。 | false |
server.undertow.threads.io |
I/O 线程数。默认值为可用的处理器数量。 | |
server.undertow.threads.worker |
Worker 线程数。默认为 I/O 线程数的 8 倍。 | |
server.undertow.url-charset |
用于解码 URL 的字符集。 | UTF-8 |