You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot集成Undertow服务无响应问题排查求助

问题分析:Spring Boot集成Undertow后XNIO I/O线程CPU占满导致服务无响应

问题概述

  • 环境配置:Spring Boot v2.7.4 + Undertow v2.2.22.Final,基于Java 11(11.0.18_10-jdk-focal)镜像部署在Docker中
  • 异常现象:服务运行一段时间后对HTTP请求无响应,执行top -H -p <PID>命令可见XNIO-1 I/O-3、XNIO-1 I/O-1等线程CPU占用接近100%
  • 已尝试无效方案:添加-Djdk.tls.acknowledgeCloseNotify=true参数、禁用TLSv1.3、降级JDK至11.0.16
  • 关联线索:已定位到UNDERTOW-2239问题与当前现象高度匹配,准备升级Undertow至2.2.24.Final

Undertow自定义配置代码:

@Configuration
class ServerConfiguration {
    @Bean
    fun embeddedServletContainerFactory(): UndertowServletWebServerFactory {
        val factory = UndertowServletWebServerFactory()
        factory.addBuilderCustomizers(UndertowBuilderCustomizer { builder ->
            builder.setServerOption(UndertowOptions.ENABLE_HTTP2, true)
        })
        return factory
    }
}

已通过VisualVM捕获到问题发生时的监控数据及线程状态。

线程CPU占满的核心原因

UNDERTOW-2239是Undertow在HTTP/2协议处理逻辑中的无限循环bug,触发场景如下:
当客户端发送的HTTP/2帧存在异常(比如帧长度不符合规范、连接异常中断时的残留帧),Undertow的HTTP/2帧解析器会进入无限循环状态,持续占用CPU资源,导致I/O线程无法处理正常请求,最终使服务失去响应。

具体到Undertow 2.2.22.Final版本,在处理CONTINUATION帧或其他类型帧时,若帧长度计算出现偏差,会导致解析器反复尝试读取无效的帧数据,陷入死循环,直接耗尽I/O线程的CPU。

之前尝试方案无效的原因

  • -Djdk.tls.acknowledgeCloseNotify=true:该参数用于修复TLS连接关闭时的通知逻辑,与HTTP/2帧解析的无限循环问题无关
  • 禁用TLSv1.3:问题根源在Undertow的HTTP/2处理代码,并非TLS协议版本导致
  • 降级JDK:此bug是Undertow的代码逻辑缺陷,与Java 11.x范围内的版本无关

验证与解决方案

  1. bug匹配验证:查看VisualVM导出的线程栈,若发现XNIO I/O线程卡在io.undertow.protocols.http2.Http2FrameParser相关方法(如processFrame、readFrameData等循环逻辑)中,即可确认是UNDERTOW-2239导致的问题。
  2. 修复方案:升级Undertow至2.2.24.Final版本,该版本已修复UNDERTOW-2239的无限循环bug。由于Spring Boot 2.7.4默认依赖Undertow 2.2.22.Final,需显式指定版本:
    • Maven配置:
      <dependencyManagement>
          <dependencies>
              <dependency>
                  <groupId>io.undertow</groupId>
                  <artifactId>undertow-core</artifactId>
                  <version>2.2.24.Final</version>
              </dependency>
              <dependency>
                  <groupId>io.undertow</groupId>
                  <artifactId>undertow-servlet</artifactId>
                  <version>2.2.24.Final</version>
              </dependency>
          </dependencies>
      </dependencyManagement>
      
    • Gradle Kotlin DSL配置:
      dependencyManagement {
          imports {
              mavenBom("io.undertow:undertow-bom:2.2.24.Final")
          }
      }
      

内容的提问来源于stack exchange,提问作者Forge_7

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 16:02:29