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

服务A使用restTemplate调用服务B,在运行300次的测试循环中,循环内每隔100个间隔抛出一个异常“Bad chunk header exception” .

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

前99个迭代 - 请求/响应头有Connection:keep-alive,body / stream以回车结尾\ r \ n结束

请求 Headers

"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]"

响应 Headers

"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]"

On 100th call - 请求标头有Connection:keep-alive,但响应haader有 Connection: close and body/stream WITHOUT carriage return \r\n
http-outgoing-0 << "end of stream"
GET请求“http://localhost:9192/rest/customers/1000000030”上的I / O错误:坏块头

请求 Headers

"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]"

响应 Headers

"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

一个 . 为什么服务器在100次呼叫后关闭连接?

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

  • 每个服务器可以处理的最大连接数为maxConnections = 10000

  • 每个连接超时connectionTimeout = 60秒

  • 最大线程在每个连接中定义可以处理多少个并发请求maxThreads = 200

  • 始终可用的最小备用线程(不是连接)= minSpareThreads = 10

  • 连接中的最大数量保持活动请求 maxKeepAliveRequests = 100(这似乎是关闭连接,并且不会发送回车作为响应正文生成缓冲区读取I / O异常的一部分)

湾关闭连接时为什么服务器没有发送终止或回车?这是Spring还是tomact问题?

C . 需要更改的方式或设置以避免这种情况? maxKeepAliveRequests未在Spring应用程序属性中公开,只有覆盖的方法是实现实现WebServerFactoryCustomizer的客户容器,然后手动覆盖 .

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