Spring Boot 内嵌容器Undertow

匿名 (未验证) 提交于 2019-12-03 00:22:01

Spring Boot内嵌容器支持Tomcat、Jetty、Undertow。为什么选择Undertow?

这里有一篇文章,时间 2017年1月26日发布的:
Tomcat vs. Jetty vs. Undertow: Comparison of Spring Boot Embedded Servlet Containers
这篇文章详细测试了Spring Boot应用在三种容器下的性能和内存使用,内含完整的测试代码和测试流程。证明了Undertow在性能和内存使用上是最好的。

在Spring Boot中使用 Undertow 而不是 Tomcat

1、Maven示例:

<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> 

2、配置Undertow,application.yml示例:

server.undertow.accesslog.dir= # Undertow access log directory. server.undertow.accesslog.enabled=false # Enable access log. server.undertow.accesslog.pattern=common # Format pattern for access logs. server.undertow.accesslog.prefix=access_log. # Log file name prefix. server.undertow.accesslog.rotate=true # Enable access log rotation. server.undertow.accesslog.suffix=log # Log file name suffix. server.undertow.buffer-size= # Size of each buffer in bytes. server.undertow.buffers-per-region= # Number of buffer per region. server.undertow.direct-buffers= # Allocate buffers outside the Java heap. server.undertow.io-threads= # Number of I/O threads to create for the worker. server.undertow.max-http-post-size=0 # Maximum size in bytes of the HTTP post content. server.undertow.worker-threads= # Number of worker threads. 

3、使用 Undertow 监听多个端口示例:

@Bean public UndertowEmbeddedServletContainerFactory embeddedServletContainerFactory() {     UndertowEmbeddedServletContainerFactory factory = new UndertowEmbeddedServletContainerFactory();     factory.addBuilderCustomizers(new UndertowBuilderCustomizer() {          @Override         public void customize(Builder builder) {             builder.addHttpListener(8080, "0.0.0.0");         }      });     return factory; } 

配置项:

# 设置IO线程数, 它主要执行非阻塞的任务,它们会负责多个连接, 默认设置每个CPU核心一个线程 # 不要设置过大,如果过大,启动项目会报错:打开文件数过多  server.undertow.io-threads=16  # 阻塞任务线程池, 当执行类似servlet请求阻塞IO操作, undertow会从这个线程池中取得线程 # 它的值设置取决于系统线程执行任务的阻塞系数,默认值是IO线程数*8  server.undertow.worker-threads=256  # 以下的配置会影响buffer,这些buffer会用于服务器连接的IO操作,有点类似netty的池化内存管理 # 每块buffer的空间大小,越小的空间被利用越充分,不要设置太大,以免影响其他应用,合适即可  server.undertow.buffer-size=1024  # 每个区分配的buffer数量 , 所以pool的大小是buffer-size * buffers-per-region  server.undertow.buffers-per-region=1024  # 是否分配的直接内存(NIO直接分配的堆外内存)  server.undertow.direct-buffers=true
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

来看看源代码:

https://github.com/undertow-io/undertow/blob/master/core/src/main/java/io/undertow/Undertow.java

ioThreads = Math.max(Runtime.getRuntime().availableProcessors(), 2);  workerThreads = ioThreads * 8;  //smaller than 64mb of ram we use 512b buffers if (maxMemory < 64 * 1024 * 1024) {     //use 512b buffers     directBuffers = false;     bufferSize = 512; } else if (maxMemory < 128 * 1024 * 1024) {     //use 1k buffers     directBuffers = true;     bufferSize = 1024; } else {     //use 16k buffers for best performance     //as 16k is generally the max amount of data that can be sent in a single write() call     directBuffers = true;     bufferSize = 1024 * 16 - 20; //the 20 is to allow some space for protocol headers, see UNDERTOW-1209 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

很显然,Undertow认为它的运用场景是在IO密集型的系统应用中,并且认为多核机器是一个比较容易满足的点,Undertow初始化假想应用的阻塞系数在0.8~0.9之间,所以阻塞线程数直接乘了个8,当然,如果对应用较精确的估测阻塞系数,可以配置上去,


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!