文章目录
当你进行Tomcat调优发现在怎么调都无法满足需求的时候,Undertow容器在性能和内存上都优于Tomcat容器,因此选择Undertow容器并进行调优是更好的选择。
Undertow优势
Undertow
是一个轻量级的、高性能的 Java Web 服务器,由 JBoss 开发并开源。它是基于非阻塞(non-blocking)
的I/O模型,具有低资源消耗和高并发处理能力。
- 支持 HTTP/2:Undertow 开箱即支持 HTTP/2,无需重写启动类路径。
- 支持 HTTP Upgrade:允许通过 HTTP 端口复用多种协议。
- 支持 Web Socket:Undertow 提供对 Web Sockets 的全面支持,包括 JSR-356 支持。
- Servlet 4.0:Undertow 支持 Servlet 4.0,包括对嵌入式 Servlet 的支持。还可以在同一部署中混合使用
Servlet 和原生 undertow 非阻塞 handler。 - 可嵌入式:只需几行代码,即可将 Undertow 嵌入应用程序或独立运行。
- 灵活性:Undertow 通过链式 handler 进行配置,可以根据需求灵活地添加功能。
在很多场景的测试下, Undertow 的性能都高于 Tomcat。天生适合作为 Spring Boot 应用的嵌入式服务器
Undertow使用
Spring Boot 默认使用Tomcat
作为嵌入式服务。所以 spring-boot-starter-web
默认依赖了 spring-boot-starter-tomcat
。
要使用 Undertow
首先要从 spring-boot-starter-web 排除 spring-boot-starter-tomcat,再添加 spring-boot-starter-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>
具体配置跟tomcat性质一样,可以参考以下官方文档,这里不做列举。除了配置对应的xml文件还可以通过实现接口实现
java
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Configuration;
@Configuration
public class UndertowConfiguration implements WebServerFactoryCustomizer<UndertowServletWebServerFactory>{
@Override
public void customize(UndertowServletWebServerFactory factory) {
factory.setBufferSize(8192);
// 其他自定义配置 ...
}
}
所以只需更换一个依赖即可使用,还是很方便的。更换完重新启动你的控制台Tomcat Start就会变成Undertow Start
Undertow性能优化
线程池配置
在SpringBoot应用的application.properties或application.yml中,可以调整Undertow的线程池设置。包括IO线程和工作线程的设置
- server.undertow.io-threads:设置IO线程数,负责处理非阻塞的网络IO。通常设置为与CPU核心数相等的值。它们会负责多个连接,不要设置过大,如果过大,启动项目会报错:打开文件数过多
- server.undertow.worker-threads:阻塞任务线程池, 当执行类似servlet请求阻塞IO操作,undertow会从这个线程池中取得线程,它的值设置取决于系统线程执行任务的阻塞系数,默认值是IO线程数*8
sh
server.undertow.io-threads=8
server.undertow.worker-threads=128
缓冲区和内存使用
- server.undertow.buffer-size:设置每个缓冲区的大小。以下的配置会影响buffer,这些buffer会用于服务器连接的IO操作,有点类似netty的池化内存管理,每块buffer的空间大小,越小的空间被利用越充分,不要设置太大,以免影响其他应用,合适即可
- server.undertow.direct-buffers:是否分配的直接内存(NIO直接分配的堆外内存)
- server.undertow.buffers-per-region:
每个区分配的buffer数量,所以pool的大小是buffer-size * buffers-per-region
sh
server.undertow.buffer-size=1024
server.undertow.direct-buffers=true
连接和请求超时
- server.undertow.max-http-post-size:设置HTTP POST请求的最大内容大小,以适应可能的文件上传或大批量数据提交。
- server.undertow.no-request-timeout:设置连接在不处理请求的情况下闲置的时间。
js
server.undertow.max-http-post-size=0 # 不限制大小,或根据实际情况调整
server.undertow.no-request-timeout=1800s # 例如,设置为30分钟
禁用无关的设置
- server.undertow.session-cookie-config:设置会话cookie的配置,可以选择不使用cookie以减少HTTP响应的大小。
- server.undertow.accesslog.enabled:根据需要启用或禁用访问日志。
js
server.undertow.session-cookie-config=none
server.undertow.accesslog.enabled=false
编程式配置
通过实现WebServerFactoryCustomizer接口来编程式地配置Undertow,可以更加灵活。
启用HTTP/2
通过配置启用Undertow支持的HTTP/2,可以提高网络传输效率。
其实本质上还是跟tomcat很像的,一些优化的方向以及配置策略,大家可以将二者好好贯通一下便于理解
Undertow与Tomcat的对比
先看一下QPS测试结果对比
Tomcat
Undertow
内存使用对比:
Tomcat
Undertow
通过测试发现,在高并发系统中,Tomcat 相对来说比较弱。在相同的机器配置下,模拟相等的请求数,Undertow 在性能和内存使用方面都是最优的。并且 Undertow 新版本默认使用持久连接,这将会进一步提高它的并发吞吐能力。所以,如果是高并发的业务系统,Undertow 是最佳选择。
场景
以下是一些Undertow 可能更适合的场景,大家在面试中或者实际业务中可以考虑是否使用
当然!以下是十个具体的业务场景,其中使用 Undertow 比 Tomcat 更加合适:
-
实时数据流处理平台:
- 场景:实时处理大规模传感器数据或金融市场数据流,例如高频交易系统或实时监控平台。
- 理由:Undertow 的非阻塞 I/O 模型适合处理高并发和低延迟的数据流。
-
在线游戏服务器:
- 场景:为多人在线游戏提供后端服务,例如游戏房间管理和玩家匹配。
- 理由:Undertow 能处理大量并发连接和低延迟请求,适合需要高性能的在线游戏环境。
-
微服务架构中的 API 网关:
- 场景:构建一个微服务架构中的 API 网关,处理来自不同服务的请求并进行负载均衡。
- 理由:Undertow 的高性能和轻量级特性使其在微服务环境中表现优异。
-
高频交易平台:
- 场景:为金融市场提供高频交易服务,需要极低的延迟和快速的请求处理。
- 理由:Undertow 的高效异步处理能力适合高频交易中的低延迟需求。
-
大规模的 RESTful API 服务:
- 场景:提供大规模的 RESTful API 服务,例如数据存储和检索服务。
- 理由:Undertow 能处理大量的 API 请求,适合高流量环境。
-
实时通信应用:
- 场景:开发实时聊天应用或实时视频会议平台,需要高并发和低延迟。
- 理由:Undertow 支持 WebSocket,适合实时双向通信应用。
-
高效的 Web 爬虫和抓取服务:
- 场景:开发一个高效的网络爬虫,抓取大量网页数据。
- 理由:Undertow 的低开销和高吞吐量适合处理大量 HTTP 请求。
-
轻量级的嵌入式 Web 服务器:
- 场景:将 Web 服务器嵌入到物联网设备或桌面应用中,例如智能家居控制中心。
- 理由:Undertow 的轻量级和嵌入式特性适合资源受限的环境。
-
动态生成的 Web 服务:
- 场景:提供动态生成内容的 Web 服务,例如广告服务器或实时报告生成。
- 理由:Undertow 的快速启动和高性能适合处理动态内容生成的需求。
-
开发和测试环境:
- 场景:在开发和测试过程中需要快速启动和关闭的 Web 服务器,例如本地测试环境中的开发应用。
- 理由:Undertow 的启动速度快且资源消耗低,适合开发和测试阶段的高效使用。