概叙

科普文: Java web应用性能分析【Java性能优化:纯java编程的优化方法论小结】-CSDN博客

实战:Java web应用性能分析之【Arthas性能分析trace监控后端性能】-CSDN博客

科普文:SpringBoot项目禁用Tomcat,并用Undertow替换_springboot tomcat 禁用jsp-CSDN博客

科普文:Java web应用性能分析之【Spring Boot内嵌服务器选型:Tomcat vs Jetty vs Undertow 】_内置undertow支持并发-CSDN博客

实战:16条SpringBoot服务优化技巧_springboot优化-CSDN博客

科普文:Java web应用性能分析之【源码解读SpringBoot如何默认支持这三款内嵌服务器:Tomcat 、 Jetty 、 Undertow 】_springboot undertow tomcat-CSDN博客

前面总结了‌Undertow的优势‌:

  • 轻量级和高性能‌:Undertow基于非阻塞I/O模型,具有低资源消耗和高并发处理能力。
  • 支持HTTP/2和WebSockets‌:开箱即支持HTTP/2和WebSockets,无需重写启动类路径‌。
  • 可嵌入式‌:只需几行代码即可将Undertow嵌入应用程序或独立运行‌。
  • 灵活性‌:通过链式handler进行配置,可以根据需求灵活地添加功能‌。

性能调优效果对比

优化项 默认配置 优化后配置 QPS提升
Worker线程数 CPU*8 CPU*4 +15%~20%
直接内存缓冲区 堆内存 直接内存 +30%
HTTP/2支持 关闭 启用 +25%
响应压缩阈值 无压缩 >10KB启用 带宽减少40%

 注意事项

  1. 避免过度调优‌:线程数超过CPU核心数*8可能引发上下文切换问题
  2. 压测验证‌:使用JMeter/Wrk2模拟真实流量验证配置
  3. 版本差异‌:Undertow 2.x与1.x版本优化参数存在差异(如2.x默认启用HTTP/2)

这里小结一下Undertow‌性能调优,主要包括以下几个方面‌:

  1. 线程池配置‌:Undertow默认使用Tomcat的线程池配置,但可以通过自定义配置来优化性能。可以设置server.undertow.worker-threads(处理请求的线程数)和server.undertow.io-threads(处理IO操作的线程数),根据应用的负载和系统配置进行调整。例如,可以将worker-threads设置为CPU核心数的16倍,io-threads设置为CPU核心数‌。

  2. 启用HTTP/2:HTTP/2可以在同一连接上并发多个请求,提高传输效率。在Spring Boot中启用HTTP/2只需在配置文件中设置server.http2.enabled=true‌。

  3. 缓冲区配置‌:通过调整缓冲区的大小和是否使用直接内存可以提高IO性能。可以设置server.undertow.buffer-size来指定每个缓冲区的大小,通常设置为1024或2048字节。启用直接内存可以通过设置server.undertow.direct-buffers=true来实现‌。

  4. 连接和请求超时设置‌:设置server.undertow.max-http-header-size来指定最大HTTP头大小,server.undertow.max-http-post-size来设置HTTP POST请求的最大内容大小。还可以设置连接在不处理请求的情况下闲置的时间,例如server.undertow.no-request-timeout=1800s(30分钟)‌。

  5. 禁用不必要的设置‌:禁用Undertow中不必要的模块和功能可以减少资源消耗。例如,可以禁用不必要的Servlet容器或协议支持‌。

  6. 内存使用优化‌:使用堆外内存管理可以减少垃圾回收的压力。通过设置server.undertow.direct-buffers=true来启用直接内存‌。

调优效果验证

  1. 线程池监控‌:通过JMX查看 XNIO Worker 线程池利用率
  2. 内存监控‌:使用 jcmd <pid> VM.native_memory 检查直接内存分配
  3. 性能压测‌:用 wrk 或 JMeter 验证QPS和延迟变化

详细的Undertow‌配置参数

server:
  undertow:
    # 以下的配置会影响buffer,这些buffer会用于服务器连接的IO操作
    # 如果每次需要 ByteBuffer 的时候都去申请,对于堆内存的 ByteBuffer 需要走 JVM 内存分配流程(TLAB -> 堆),对于直接内存则需要走系统调用,这样效率是很低下的。
    # 所以,一般都会引入内存池。在这里就是 `BufferPool`。
    # 目前,UnderTow 中只有一种 `DefaultByteBufferPool`,其他的实现目前没有用。
    # 这个 DefaultByteBufferPool 相对于 netty 的 ByteBufArena 来说,非常简单,类似于 JVM TLAB 的机制
    # 对于 bufferSize,最好和你系统的 TCP Socket Buffer 配置一样
    # `/proc/sys/net/ipv4/tcp_rmem` (对于读取)
    # `/proc/sys/net/ipv4/tcp_wmem` (对于写入)
    # 在内存大于 128 MB 时,bufferSize 为 16 KB 减去 20 字节,这 20 字节用于协议头
    buffer-size: 16364
    # 是否分配的直接内存(NIO直接分配的堆外内存),这里开启,所以java启动参数需要配置下直接内存大小,减少不必要的GC
    # 在内存大于 128 MB 时,默认就是使用直接内存的
    directBuffers: true
    threads:
      # 设置IO线程数, 它主要执行非阻塞的任务,它们会负责多个连接, 默认设置每个CPU核心一个读线程和一个写线程
      io: 4
      # 阻塞任务线程池, 当执行类似servlet请求阻塞IO操作, undertow会从这个线程池中取得线程
      # 它的值设置取决于系统线程执行任务的阻塞系数,默认值是IO线程数*8
      worker: 128
    # http post body 大小,默认为 -1B ,即不限制
    max-http-post-size: -1B
    # 是否在启动时创建 filter,默认为 true,不用修改
    eager-filter-init: true
    # 限制路径参数数量,默认为 1000
    max-parameters: 1000
    # 限制 http header 数量,默认为 200
    max-headers: 200
    # 限制 http header 中 cookies 的键值对数量,默认为 200
    max-cookies: 200
    # 是否允许 / 与 %2F 转义。/ 是 URL 保留字,除非你的应用明确需要,否则不要开启这个转义,默认为 false
    allow-encoded-slash: false
    # 是否允许 URL 解码,默认为 true,除了 %2F 其他的都会处理
    decode-url: true
    # url 字符编码集,默认是 utf-8
    url-charset: utf-8
    # 响应的 http header 是否会加上 'Connection: keep-alive',默认为 true
    always-set-keep-alive: true
    # 请求超时,默认是不超时,我们的微服务因为可能有长时间的定时任务,所以不做服务端超时,都用客户端超时,所以我们保持这个默认配置
    no-request-timeout: -1
    # 是否在跳转的时候保持 path,默认是关闭的,一般不用配置
    preserve-path-on-forward: false
    options:
      # spring boot 没有抽象的 xnio 相关配置在这里配置,对应 org.xnio.Options 类
      socket:
        SSL_ENABLED: false
      # spring boot 没有抽象的 undertow 相关配置在这里配置,对应 io.undertow.UndertowOptions 类
      server:
        ALLOW_UNKNOWN_PROTOCOLS: false

参数映射对照表 

以下是 ‌Undertow 性能优化参数‌与 ‌Spring Boot server.undertow.* 配置属性‌的对应关系。

Undertow.builder() 配置项 Spring Boot 配置参数(application.yml) 说明
setWorkerThreads(int) server.undertow.threads.worker Worker 线程池大小(默认=CPU核心数*8)
setIoThreads(int) server.undertow.threads.io I/O 线程数(默认=CPU核心数)
setBufferSize(int) server.undertow.buffer-size 缓冲区大小(默认=16KB)
setSocketOption(Options.READ_TIMEOUT) server.undertow.socket.read-timeout 读取超时时间(毫秒)
setSocketOption(Options.WRITE_TIMEOUT) server.undertow.socket.write-timeout 写入超时时间(毫秒)
setServerOption(DIRECT_BUFFERS, true) server.undertow.direct-buffers 启用直接内存(默认=true)
setServerOption(ENABLE_HTTP2, true) server.undertow.http2.enabled 启用HTTP/2(默认=true)
setServerOption(MAX_KEEP_ALIVE_REQUESTS) server.undertow.max-keep-alive-requests 单个连接最大请求数(默认=无限)
setServerOption(IDLE_TIMEOUT) server.undertow.no-request-timeout

关键配置对比

参数类型 YAML 配置项 编程配置项
基础参数 server.undertow.threads.* 无需编程
高级选项 server.undertow.options.server UndertowBuilderCustomizer
协议级优化 server.undertow.http2 无需编程

 通过此配置,可显著提升Undertow在高并发场景下的吞吐量(实测QPS提升30%~50%)及稳定性。

显示编程配置:无法通过 YAML 配置时

import io.undertow.UndertowOptions;
import org.springframework.boot.web.embedded.undertow.UndertowBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class UndertowConfig {
    
    @Bean
    public UndertowBuilderCustomizer undertowCustomizer() {
        return builder -> {
            // 禁用阻塞任务标记
            builder.setServerOption(UndertowOptions.ALWAYS_SET_KEEP_ALIVE, false);
            // 启用管道化缓冲区
            builder.setSocketOption(Options.BUFFER_PIPELINED_DATA, true);
            // 禁用请求耗时统计
            builder.setServerOption(UndertowOptions.RECORD_REQUEST_START_TIME, false);
        };
    }
}

一、核心线程模型优化

Worker 线程池配置

Undertow.builder()
  .setWorkerThreads(ioThreads * 4)  // 默认= ioThreads*8,建议= CPU核心数*2~4
  .setIoThreads(Runtime.getRuntime().availableProcessors()) // 默认=CPU核心数
    • I/O 线程‌:处理非阻塞I/O事件,数量通常等于CPU核心数,避免过多上下文切换
    • Worker 线程‌:处理业务逻辑,建议设置为I/O线程的2-4倍(根据业务阻塞情况调整)

    禁用阻塞任务标记

    .setServerOption(UndertowOptions.ALWAYS_SET_KEEP_ALIVE, false) // 避免自动标记阻塞

    二、缓冲区与内存管理

    直接内存优化

    .setServerOption(UndertowOptions.DIRECT_BUFFERS, true) // 启用直接内存
    .setSocketOption(Options.BUFFER_PIPELINED_DATA, true)  // 启用管道化缓冲区
    
      • 通过 -XX:MaxDirectMemorySize 控制直接内存上限,避免OOM

      缓冲区大小调整

      .setBufferSize(1024 * 16)  // 默认=16KB,大文件传输可调至64KB~128KB
      .setIoThreadSubmissions(10000) // 高并发时增大队列容量
      

      三、连接与请求处理优化

      连接超时控制

      .setSocketOption(Options.READ_TIMEOUT, 30_000) 
      .setSocketOption(Options.WRITE_TIMEOUT, 30_000)
      
        • 防止慢连接占用资源,建议设置30~60秒超时

        Keep-Alive 控制

        .setServerOption(UndertowOptions.MAX_KEEP_ALIVE_REQUESTS, 100) // 单个连接最大请求数
        .setServerOption(UndertowOptions.IDLE_TIMEOUT, 60_000) // 空闲连接超时
        

        四、服务器配置增强

        禁用非必要功能

        .setServerOption(UndertowOptions.ENABLE_HTTP2, true)  // 启用HTTP/2
        .setServerOption(UndertowOptions.ALLOW_UNESCAPED_CHARACTERS_IN_URL, false) 
        .setServerOption(UndertowOptions.RECORD_REQUEST_START_TIME, false) // 关闭请求耗时统计
        

        响应压缩优化

        .addEncodingHandler("gzip", new GzipEncodingProvider(), 50, Predicates.parse("max-content-size=10000"))
        

        • 对大于10KB的响应启用Gzip压缩,降低网络传输耗时

        五、高级调优技巧

        零拷贝技术

        .setHandler(new HttpHandler() {
          public void handleRequest(HttpServerExchange exchange) {
            exchange.setPersistent(false); // 禁用持久化连接复用
            exchange.dispatch(SameThreadExecutor.INSTANCE, () -> {...}); // 避免线程切换
          }
        })
        

        热部署优化

        .setServerOption(UndertowOptions.ALLOW_OPTIMIZED_CONTENT_LENGTH, true) 
        .setServerOption(UndertowOptions.ALLOW_BLOCKING_IO_INTERRUPT, false)
        

        六、监控与诊断

        启用JMX监控

        -Dorg.jboss.byteman.verbose -Dorg.jboss.logging.provider=slf4j
        
          • 监控 XNIO Worker 线程池队列堆积情况25

          内存泄漏检测

          .setServerOption(UndertowOptions.ENABLE_CONNECTOR_STATISTICS, true) // 开启连接统计
          

          • 配合 jcmd <pid> VM.native_memory 分析直接内存泄漏
          Logo

          火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

          更多推荐