记一次httpclient Connection reset问题定位

Posted wuweidong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记一次httpclient Connection reset问题定位相关的知识,希望对你有一定的参考价值。

 

问题:某业务系统在运行一段时间后,某个API一定概率偶现Connection reset现象。

技术图片

问题定位:

首先想到的是要本地复现出这个问题,但一直复现不出来。

1、根据线上问题相关日志判断应该是有部分丢包情况。可能是系统参数的设置问题,如果在  net.ipv4.tcp_tw_recycle 、net.ipv4.tcp_timestamps 均设置为1的情况下,可能会因为timestamps时间戳校验导致部分丢包。
2、查询了线上配置,lvs、引擎集群的系统参数配置,均是net.ipv4.tcp_tw_recycle=0,net.ipv4.tcp_timestamps=1,不具备出现1描述问题的条件。
3、排查lvs、引擎服务器上和丢包有关日志。如网卡netdev backlog队列是否溢出,网卡Ring Buffer设置值,半连接队列溢出值等,tcp的log等,均无异常情况。
4、在开发测试环境模拟多个客户端(5)个同时压测,jmeter长/短连接、Timeout时间、HttpClient版本,也未复现该问题,将客户端的配置改成net.ipv4.tcp_tw_recycle=1,net.ipv4.tcp_timestamps=1,来压测,排查下是否是客户端系统参数引起的,看下是否能重现,也未重现该问题。
5、通过httpclient编写api定时访问接口,短链接下未复现。
6、通过httpclient编写api访问接口,使用httpclient连接池,长连接下复现,每次任务sleep 随机0-60s。(考虑服务端keepalive_timeout时间是60s)。发现出现同样问题。判断是长连接情况下导致。
7、研究了下http连接池的长连接原理,默认策略如下。设置的客户端默认超时时间为-1,即永远不失效,重写该方法,设置时间为20s。发现不会出现该问题。
技术图片

8、但考虑服务端有设置60s的超时时间,不会出现那么大概率的问题

9、可以通过在返回header头中加入timeout时间,强制给客户端设置一个长连接超时时间。如

技术图片

10、去掉默认策略。(因为特殊原因不能让客户端改)仍然不能解决问题。

11、修改测试任务发送的时间,发现sleep时间在30S内不会出现该问题,sleep时间在30-60s会50%概率出现。

12、查询所有链路上的(客户端、lvs、nginx)的相关系统参数超时配置,修改均无效。

13、在设置为32S sleep的场景抓包分析。客户端抓包如下,发现在32S用同一个连接去发送数据后,服务端返回了一个RST(重置连接)信号。但对比服务端nginx日志,并未发现收到该包。怀疑问题出现在LVS

技术图片

 14、LVS上抓包,发现是LVS上回复了RST重置连接的包。检查LVS配置

 

 技术图片

15、发现有个如下设置:

ipvsadm --set 30 6 60

 技术图片

看说明,应该不会影响功能。在抓包的结果中也发现,客户端会重新换个连接,重新发一次请求。

 

技术图片

16、思考良久,在测试代码中加入了catch,发现catch后就不会进行重新选取连接重试。导致BUG。

17、查看LVS官方文档,发现三个参数和baidu搜出来的结果不一致。该参数会使TCP连接超时。

技术图片

18、修改参数为set 60 6 60,(加上参数的目的是为了方式长连接 的四层tcp耗尽攻击)。问题解决。

至此,问题定位完成。要保证lvs的tcp连接超时时间和nignx的keepaliveded超时时间一致才会出现该问题。

参考:http://www.austintek.com/LVS/LVS-HOWTO/HOWTO/LVS-HOWTO.ipvsadm.html

https://dongliboyqq.iteye.com/blog/2409122

 

以上是关于记一次httpclient Connection reset问题定位的主要内容,如果未能解决你的问题,请参考以下文章

记一次解决RestTemplate和HttpClient请求结果乱码的问题

问题记录记一次ConnectionTimeout问题排查

记一次CVE-2017-10271

记一次 .NET 某企业OA后端服务 卡死分析

记一次排查mysql数据库连接未关闭问题的过程

Angular6 - GET net::ERR_CONNECTION_REFUSED 的 HttpClient 错误处理