spring-boot - 响应正文错误的 block header - GET 请求上的 I/O 错误

标签 spring-boot embedded-tomcat-8

设置 - 2 个 Rest 服务,spring-boot 2.x,嵌入式 tomcat 8.x

服务 A 使用 RestTemplate 调用服务 B,在运行 300 次的测试循环中,循环内每第 100 个间隔都会抛出异常“Bad chunk header 异常”。

启用调试( <logger name="org.apache.http" level="DEBUG"/> ),分析如下:

前 99 次迭代 - 请求/响应 header 具有 Connection: keep-alive 且正文/流以回车符结尾\r\n

请求 header

"GET /rest/customers/1000000030 HTTP/1.1[\r][\n]"
"Accept-Language: en-us[\r][\n]"
"Accept: application/json[\r][\n]"
"Content-Type: application/json[\r][\n]"
"Host: localhost:9192[\r][\n]"
"Connection: Keep-Alive[\r][\n]"
"User-Agent: Apache-HttpClient/4.5.5 (Java/1.8.0_25)[\r][\n]"
"Accept-Encoding: gzip,deflate[\r][\n]"
"[\r][\n]"

响应 header

"HTTP/1.1 200 [\r][\n]"
"X-Content-Type-Options: nosniff[\r][\n]"
"X-XSS-Protection: 1; mode=block[\r][\n]"
"Cache-Control: no-cache, no-store, max-age=0, must-revalidate[\r][\n]"
"Pragma: no-cache[\r][\n]"
"Expires: 0[\r][\n]"
"X-Frame-Options: DENY[\r][\n]"
"X-Content-Type-Options: nosniff[\r][\n]"
"X-Content-Type-Options: nosniff[\r][\n]"
"X-Content-Type-Options: nosniff[\r][\n]"
"Cache-Control: no-cache, no-store, max-age=0, must-revalidate[\r][\n]"
"Pragma: no-cache[\r][\n]"
"Expires: 0[\r][\n]"
"Connection: close[\r][\n]"
"Transfer-Encoding: chunked[\r][\n]"
"Date: Wed, 03 Oct 2018 00:31:53 GMT[\r][\n]"
"Content-Type: application/json;charset=UTF-8[\r][\n]"
"[\r][\n]"
"{"customerNumber":"1000000030"}[\r][\n]"

第 100 次调用 - 请求 header 具有 Connection: keep-alive,但响应 haader 具有 Connection: close 和 body/stream 不带回车符\r\n
http-outgoing-0 <<“流结束”
http://localhost:9192/rest/customers/1000000030”的 GET 请求出现 I/O 错误:错误的 block header

请求 header

"GET /rest/customers/1000000030 HTTP/1.1[\r][\n]"
"Accept-Language: en-us[\r][\n]"
"Accept: application/json[\r][\n]"
"Content-Type: application/json[\r][\n]"
"Host: localhost:9192[\r][\n]"
"Connection: Keep-Alive[\r][\n]"
"User-Agent: Apache-HttpClient/4.5.5 (Java/1.8.0_25)[\r][\n]"
"Accept-Encoding: gzip,deflate[\r][\n]"
"[\r][\n]"

响应 header

"HTTP/1.1 200 [\r][\n]"
"X-Content-Type-Options: nosniff[\r][\n]"
"X-XSS-Protection: 1; mode=block[\r][\n]"
"Cache-Control: no-cache, no-store, max-age=0, must-revalidate[\r][\n]"
"Pragma: no-cache[\r][\n]"
"Expires: 0[\r][\n]"
"X-Frame-Options: DENY[\r][\n]"
"X-Content-Type-Options: nosniff[\r][\n]"
"X-Content-Type-Options: nosniff[\r][\n]"
"X-Content-Type-Options: nosniff[\r][\n]"
"Cache-Control: no-cache, no-store, max-age=0, must-revalidate[\r][\n]"
"Pragma: no-cache[\r][\n]"
"Expires: 0[\r][\n]"
"Connection: close[\r][\n]"
"Transfer-Encoding: chunked[\r][\n]"
"Date: Wed, 03 Oct 2018 00:31:53 GMT[\r][\n]"
"Content-Type: application/json;charset=UTF-8[\r][\n]"
"[\r][\n]"
"{"customerNumber":"1000000030"}" <- MISSING \r\n

a.为什么服务器在 100 次调用后关闭连接?

似乎这就是原因 - Tomcat 8 具有 NIO 连接器默认值:

  • 每台服务器可以处理的最大连接数为 最大连接数 = 10000
  • 每个连接超时connectionTimeout = 60 秒
  • 最大线程数定义每个连接内可以处理的并发请求数 maxThreads = 200
  • 始终可用的最小空闲线程(不是连接) = minSpareThreads = 10
  • 连接内保持事件请求的最大数量ma​​xKeepAliveRequests = 100(这似乎是关闭 连接,并且不发送回车作为响应的一部分 body 生成 Buffer Read I/O 异常)

b.关闭连接时为什么服务器不发送终止或回车?这是Spring还是tomact的问题?

c.需要如何或更改哪些设置来避免这种情况? maxKeepAliveRequests 未在 Spring 应用程序属性中公开,唯一的覆盖方法是实现一个实现 WebServerFactoryCustomizer 的客户容器,然后手动覆盖。

请告知这是否是服务器上连接关闭事件的错误?

最佳答案

我在使用RestTemplate交换功能时遇到了这个问题,我只是过滤了Connection header,然后错误就消失了。

关于spring-boot - 响应正文错误的 block header - GET 请求上的 I/O 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52618322/

相关文章:

java - jar 文件的 shell 脚本

java - 为 Spring 验证框架定制 validator

java - 为什么 Spring-Boot 应用程序在创建 CXF SOAP 服务步骤时卡住?

java - SpringBoot 2.1.3 : Embedded Tomcat Logging

java - 如何替换@MockBean?

java - Spring Boot 自定义 http 错误响应?

java - Flux 返回空对象

java - Heroku webapp-runner JNDI 命名,资源不可用

spring - 如何在spring boot embedded tomcat中获取当前客户端请求线程数?

spring - 如何在 Grails 3.1.6+ 中配置 SSL?