【发布时间】:2018-10-03 01:04:47
【问题描述】:
设置 - 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 和正文/流以回车符结尾 \r\n
请求标头
"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]"
响应标头
"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 次调用 - 请求标头有 Connection: keep-alive,但响应 haader 有 Connection: close 和 body/stream 没有回车 \r\n
http-outgoing-0
“http://localhost:9192/rest/customers/1000000030”的 GET 请求出现 I/O 错误:块标头错误
请求标头
"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]"
响应标头
"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 次调用后关闭连接?
似乎这就是原因-带有 NIO 连接器默认值的 Tomcat 8:
- 每台服务器可以处理的最大连接数为 最大连接数 = 10000
- 每次连接超时connectionTimeout = 60 秒
- 最大线程数定义每个连接内可以同时处理多少个请求 maxThreads = 200
- 始终可用的最小备用线程(不是连接) = minSpareThreads = 10
- 连接内保持活动请求的最大数量 maxKeepAliveRequests = 100(这似乎正在关闭 连接,并且不发送回车作为响应的一部分 正文生成缓冲区读取 I/O 异常)
b.关闭连接时为什么服务器不发送终止或回车?这是 Spring 还是 tomact 问题?
c。需要如何更改或更改什么设置来避免这种情况? maxKeepAliveRequests 没有在 Spring 应用程序属性中公开,唯一的覆盖方法是实现一个客户容器,实现 WebServerFactoryCustomizer,然后手动覆盖。
请告知这是否是服务器上连接关闭事件的错误?
【问题讨论】:
-
您好,您找到解决方案了吗?看来我对 Spring Boot 2.1.4 有同样的问题
标签: spring-boot embedded-tomcat-8