You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

Spring Boot 2.7.4调用API时偶现HTTP请求头解析错误求助

Spring Boot 2.7.4 + Tomcat 9 HTTP请求头解析EOFException问题排查

问题场景

基于Spring Boot 2.7.4开发的Web服务,示例接口:

@GetMapping("api/datas/options")
public List<Option> getAllOptions(){
    return pomppdoptRepository.findAll();   
}

Postman请求该接口能正常返回200 OK,但日志中频繁出现java.io.EOFException的HTTP请求头解析错误。错误触发规律:

  • 立即重发请求无报错
  • 等待几分钟后请求,错误重现
  • 并发发送多个请求时也会触发错误

相关日志与配置

请求日志

Received [GET /api/datas/options HTTP/1.1
Authorization: Bearer token
User-Agent: PostmanRuntime/7.43.3
Accept: */*
Cache-Control: no-cache
Postman-Token: 57c14232-ed07-4247-a00a-19cf2eb34d5e
Host: localhost:8082
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Cookie: JSESSIONID=90155C405D55A5E7968C4617A05BE184

]

错误日志片段

2025-04-02 10:07:41.383 DEBUG 24432 --- [nio-8082-exec-5] o.apache.coyote.http11.Http11Processor   : Error parsing HTTP request header

java.io.EOFException: null
    at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.fillReadBuffer(NioEndpoint.java:1340) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
    ...
2025-04-02 10:07:41.383 DEBUG 24432 --- [nio-8082-exec-5] o.apache.coyote.http11.Http11Processor   : Error state [CLOSE_CONNECTION_NOW] reported while processing request

java.io.EOFException: null
    at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.fillReadBuffer(NioEndpoint.java:1340) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
    ...

项目application.yml配置

logging:
  level:
    org.apache.coyote.http11: DEBUG
    org.springframework.web: DEBUG
    org.apache.coyote.http11.Http11Processor: DEBUG

server:
  tomcat:
    threads:
      max: 200
      min-spare: 10
    accesslog:
      enabled: true
      pattern: "%h %l %u %t \"%r\" %s %b"
    connection-timeout: 60000  # 60秒
    keep-alive-timeout: 60000  # 60秒
  port: 8082

spring:
  datasource:
    hikari:
      connection-test-query: SELECT 1
      maximum-pool-size: 20
      minimum-idle: 5
      idle-timeout: 60000
      max-lifetime: 1800000
      connection-timeout: 30000
  jpa:
    show-sql: true
    open-in-view: false
    properties:
      hibernate:
        format_sql: true
    hibernate:
      naming:
        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
        implicit-strategy: org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl

排查与解决思路

  • 调整Tomcat Keep-Alive参数
    当前keep-alive-timeoutconnection-timeout均为60秒,当客户端复用已被服务端超时关闭的长连接时,会触发EOFException。可尝试:

    1. 缩短keep-alive-timeout至30秒,确保服务端先于客户端关闭空闲连接,避免客户端复用失效连接
    2. 临时关闭Keep-Alive验证问题:添加server.tomcat.keep-alive-enabled=false,观察错误是否消失
  • 验证客户端连接复用行为
    Postman默认复用Keep-Alive连接,可在请求头中设置Connection: close关闭连接复用,测试是否还会出现错误,以此确认是否为连接复用导致的问题。

  • 升级Tomcat版本
    Tomcat 9.0.65存在部分NIO连接处理的已知Bug,Spring Boot 2.7.x可升级至9.0.80+版本修复相关问题。Maven项目可在pom.xml中指定版本:

    <properties>
        <tomcat.version>9.0.80</tomcat.version>
    </properties>
    
  • 排查网络中间件
    防火墙、反向代理(如Nginx)可能主动关闭空闲连接,导致服务端读取请求时遇EOF。检查相关中间件的连接超时配置,确保与Tomcat参数匹配。

  • 调整Tomcat缓冲区配置
    增大读取缓冲区大小,避免因缓冲区不足引发的读取异常:

    server:
      tomcat:
        max-http-header-size: 8192
        socket:
          buffer-size: 8192
    

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

火山引擎 最新活动