Tomcat9.0.63搭配高版本OpenJDK8触发EOFException异常求助
根因定位
该java.io.EOFException是Tomcat 9.0.63的HTTP/2异步解析边界缺陷,与OpenJDK 8u252及以上版本的TLS NIO实现变更不兼容导致,触发链路完全匹配版本交叉验证结果:
- 异常触发点位于HTTP/2连接建立后的序言读取阶段:从堆栈可以看到错误抛出在
Http2AsyncParser.readConnectionPreface方法,属于HTTP/2连接初始化的首个数据读取步骤。 - OpenJDK 8u252版本正式默认开启TLS ALPN支持,同时修改了NIO SSL通道的读取返回逻辑:此前版本在SSL握手完成后未拿到完整应用层数据时会阻塞等待,8u252及更高版本在暂无可读HTTP/2序言数据时会直接返回-1(流结束标识)。
- Tomcat 9.0.36~9.0.63版本重构了HTTP/2的异步解析逻辑,但未对「SSL通道暂时无数据」和「连接真实断开」两种返回-1的场景做区分,直接将无数据场景判定为连接中断抛出EOF异常;9.0.35及更早版本使用同步HTTP/2解析逻辑,不会触发该判断分支,8u242及更早JDK版本未修改NIO SSL读取逻辑,也不会触发异常。
- 当前配置中443、9443两个HTTPS端口均开启了HTTP/2升级支持,所有协商到HTTP/2协议的HTTPS请求都会稳定触发该问题。
修复方案
按生产环境推荐优先级排序:
- 升级Tomcat版本至9.0.64及以上。Apache Tomcat官方在9.0.64版本正式修复了该HTTP/2异步读取的边界判断缺陷,修复后读取返回-1时会先校验SSL通道状态、待读缓存数据,不会误判连接中断,与OpenJDK 8u252及以上版本完全兼容,无功能损失,是最优修复方案。
- 若暂时无法升级Tomcat,可临时移除两个HTTPS Connector配置中的
<UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />配置行,关闭HTTP/2支持,服务将降级使用HTTP/1.1协议处理请求,不会再触发该异常,缺点是无法使用HTTP/2的多路复用、头部压缩等特性。 - 若必须保留HTTP/2支持且短期无法升级Tomcat,可将OpenJDK版本回退至8u242-b08及更早版本,避开JDK侧的TLS NIO逻辑变更,但旧版本JDK存在多个已公开的高危安全漏洞,生产环境不推荐使用该方案。
- 临时应急场景可给JVM增加启动参数
-Djdk.tls.acknowledgeCloseNotify=true,调整TLS层连接关闭通知的处理逻辑,可覆盖大部分异常触发场景,但无法100%解决所有边界case,仅适合短期过渡使用。
内容的提问来源于stack exchange,提问作者MLM
相关产品推荐
相关产品推荐

