1. 背景
有两个服务,A和B。其中B部署了Nginx网关,A通过HttpClient调用B的接口。
2. 问题现象
1)A调用B的接口时偶尔抛出如下异常:
java.net.SocketTimeoutException: Read timed out
2)发生异常时,A的线程总是阻塞30秒
3)A如果连续调用B的接口,比较稳定;隔一段时间调用一次,则容易发生异常
3. 调查过程
大胆猜测1:网络不稳定?
小心求证:
1)查看B服务的日志,未收到请求,说明请求确实未抵达B服务
2)Nginx网关日志暂无权限,未查看
3)通过curl命令从A服务机器检查B服务机器网络状况,显示很通畅,网络因素无法确证,此路不通
大胆猜测2:错误的使用了HttpClient?
小心求证:
所有post请求调用结束后,添加了释放连接的操作,证实无效
大胆猜测3:长连接超时?
小心求证:
1)多次测试发现,5分钟内连续请求,都能正常返回;两次请求间隔5分钟以上,必然超时
=》说明B服务长连接超时时间为5分钟
2)使用tcpdump抓包,发现发生超时时,A服务在30秒内向B服务发送了多个相同的数据包,而B服务没有任何ACK
=》说明B服务5分钟后主动切断了长连接