记一次线上异常思考【HTTP】
背景
支付时向渠道请求,偶发的出现了NoHttpResponseException异常,频次不高,没有规律。
异常请求重试之后数据都是正常的。
这种可以排除是业务代码问题,问题可能就出现再HttpClient运用上了。
简要分析和解决方案
项目中应用到了长连接可以回顾下 :
- HTTP的keep-alive一般我们都会带上中间的横杠,普通的HTTP连接是客户端连接上服务端,
然后结束请求后,由客户端或者服务端进行http连接的关闭。下次再发送请求的时候,
客户端再发起一个连接,传送数据,关闭连接。这么个流程反复。
但是一旦客户端发送connection: keep-alive头给服务端,
且服务端也接受这个keep-alive的话,这个连接就可以复用了。
一个HTTP处理完之后,另外一个HTTP数据包也直接从这个连接发送。
减少新建和断开TCP连接的消耗。
<br/>
<br/> - TCP的keepalive是侧重在保持客户端和服务端的连接,
一方会不定期发送心跳包给另一方,
没有断掉一方的定时发送几次心跳包。如果间隔发送几次,
对方都返回的是RST,而不是ACK,那么就释放当前连接。
从HTTP长连接可以推测到:进入客户端刚刚获取到了HTTP的连接,而服务端httpd检测到存活时间超时断开了TCP。断开后HTTP请求就会被拒绝掉,就会导致NoHttpResponseException。
异常复现:
在程序获取到连接后调用之前断点(在建立长连接后),等待服务端TCP断开,然后触发调用
可以看下抓包的数据(192. 为本地) (172.* 为远程),超过一段时间TCP没有通讯,远程服务端会断开TCP
处理方案通过补偿机制重试:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。