HttpClient请求外部服务器NoHttpResponseException

6 篇文章 0 订阅
4 篇文章 0 订阅

针对跟外部对接,使用httpclient进行请求可能会报NoHttpResponseException,原因有可能是当时target服务器负载过大,或者服务端连接空闲自动挂起,或者客户端的http请求机制跟服务端不一致(这次就是这个原因,客户端使用socket的空闲连接,服务器端是短连接)。

刚开始发现NoHttpResponseException,网上也查了一些资料,设置HttpClients的setRetryHandler,增加针对NoHttpResponseException的重试机制

setRetryHandler参考文章:https://blog.csdn.net/siantbaicn/article/details/80854528

                                            https://blog.csdn.net/liubenlong007/article/details/78180333

发现公共方法中重试次数3改为了1,也就是没有重试机制,沟通后改成3,发布生产环境,结果发现还是有报NoHttpResponseException的数据,虽然数据量减少。继续排查

本地写一个压测的简单方法,进行接口测试,结果本地没有报NoHttpResponseException,排除服务器负载过大的情况,况且目标服务器用的f5硬负载均衡,抗负载能力应该是很强的。

因为不知道合作方提供的服务器配置情况,询问也是很久没回复,但是不能影响业务啊,那就是抓取网络包进行查看。

tcpdump 生成scp文件,然后wireshark软件进行查看。

sudo tcpdump -i eth0 -w lmstcp.cap host 1.1.0.52 and tcp port 8080 &

发现NoHttpResponseException的一个http流,发现服务器在http处理200后,向客户端发出了挥手FIN,ACK,客户端也进行ACK,但此时客户端又来了一个http请求,而且是使用了前面但TCP,服务器端直接进行了RST,丢弃掉该次链接。

经过抓包发现,服务端对http请求完后就断开了tcp,但是客户端是使用的http client连接池,共享了tcp socket的,发现socket是有30S空闲时间的,此时新的http过来时沿用了空闲中的tcp,修改为0,让采用新创建socket,继续发版本,进行数据测试。

// 可用空闲连接过期时间,重用空闲连接时会先检查是否空闲时间超过这个时间,如果超过,释放socket重新建立
        connManager.setValidateAfterInactivity(0);//改为0 立即释放socket

结果还是存在NoHttpResponseException数据,继续查资料,空闲时间为0了,但是socket还是会被回收到池中的,回收池中复用策略

  • 如果request首部中包含Connection:Close,不复用

  • 如果response中Content-Length长度设置不正确,不复用

  • 如果response首部包含Connection:Close,不复用

  • 如果reponse首部包含Connection:Keep-Alive,复用

  • 都没命中的情况下,如果HTTP版本高于1.0则复用

继续修改,将请求的request的Header中response.setHeader("connection", "close");强制tcp不回收到池中,相当于短链接请求。

 

经过这一问题排查,对网络通信更加了解,http tcp的请求等,还是需要懂原理,这样排查问题能更迅速定位原因,同时能读源码还是看源码解决问题,下面是解决问题时看到的文章。

 

针对keep-alive的http tcp的解释,http1.0需要手动开启,http1.1后默认开启,参考文章:

https://www.cnblogs.com/hukey/p/5481173.html

https://blog.csdn.net/weixin_37672169/article/details/80283935

针对网络通信的文章,下面的集合文章比较全了:

https://blog.csdn.net/yi_master/article/details/80579134

nginx的抓包分析文章:

https://segmentfault.com/a/1190000018011857

tcpdump,以及wireshark工具:

https://blog.csdn.net/qq_19167629/article/details/83088878

https://blog.csdn.net/qq_28699375/article/details/78860016

wireshark过滤规则,以及使用方法:

https://blog.csdn.net/wojiaopanpan/article/details/69944970

wireshark tcp seq ack说明:

https://blog.csdn.net/wang7dao/article/details/16805337

httpclient源码解析:

https://www.cnblogs.com/shoren/p/httpclient-leaseConnection.html

https://www.cnblogs.com/cherish010/p/9242756.html

http connection close:

https://www.cnblogs.com/liluxiang/p/9474907.html

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值