springboot中使用undertow容器
1、undertow介绍
官网:https://undertow.io/
Undertow 是一个轻量级的、高性能的 Java Web 服务器,由 JBoss 开发并开源。它是基于非阻塞(non-blocking)的I/O模型,具有低资源消耗和高并发处理能力。Undertown 的优势如下:
- 支持 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 应用的嵌入式服务器!
说明:tomcat主要支持以下几种IO 模型:
- BIO(Blocking I/O):传统的同步阻塞IO,每个请求都对应一个线程,在处理速度慢的情况下容易造成线程堆积。
- NIO(Non-blocking I/O):使用JDK 1.4 和 java.nio 包,支持非阻塞I/O,能够通过少量线程处理大量并发连接,提高了服务器的吞吐量和并发能力。Tomcat 8 及以上版本默认就运行在NIO 模式下。
- APR(Apache Portable Runtime):通过JNI 调用Apache HTTP 服务器的核心动态链接库,利用操作系统的非阻塞IO 能力,可以大幅提升处理静态文件和高并发的性能。
- AIO(Asynchronous I/O,也称NIO.2):从JDK 7 开始支持的异步非阻塞IO,是目前最先进的IO 模型。
2、springboot中使用undertow
Spring Boot 默认使用 Tomcat 作为嵌入式 Servlet 服务器,所以 spring-boot-starter-web 默认依赖了 spring-boot-starter-tomcat。
要使用 Undertow 首先要从 spring-boot-starter-web 排除 spring-boot-starter-tomcat,再添加 spring-boot-starter-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><exclusions><!-- 排除 undertow-websockets-jsr 依赖 --><exclusion><groupId>io.undertow</groupId><artifactId>undertow-websockets-jsr</artifactId></exclusion></exclusions>
</dependency>
在springboot中指定端口:(同tomcat)
server.port=8081
server.servlet.session.timeout=2M
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 |
3、性能对比
1)吞吐量和响应时间
2)cpu使用率:Undertow < Jetty < Tomcat
3)内存使用率:Undertow < Jetty < Tomcat
4)线程数:Undertow < Jetty < Tomcat