HttpClient Post报错org.apache.http.NoHttpResponseException

软件版本:httpclient4.5.6,httpcore4.4.10,httpclient-cache4.5.6,httpmime4.5.6

最近使用httpclient post调用第三方http服务时出现网路异常,无法获取响应。

org.apache.http.NoHttpResponseException: 139.159.143.73:31820 failed to respond
        at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:143)
        at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:57)
        at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:261)
        at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:165)
        at org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:167)
        at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:272)
        at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:124)
        at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:271)
        at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
        at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
        at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
        at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
        at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
        at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:107)
        
java.net.SocketTimeoutException: Read timed out
        at java.net.SocketInputStream.socketRead0(Native Method)
        at java.net.SocketInputStream.read(SocketInputStream.java:153)
        at java.net.SocketInputStream.read(SocketInputStream.java:122)
        at org.apache.http.impl.io.AbstractSessionInputBuffer.fillBuffer(AbstractSessionInputBuffer.java:166)
        at org.apache.http.impl.io.SocketInputBuffer.fillBuffer(SocketInputBuffer.java:90)
        at org.apache.http.impl.io.AbstractSessionInputBuffer.readLine(AbstractSessionInputBuffer.java:281)
        at org.apache.http.impl.conn.LoggingSessionInputBuffer.readLine(LoggingSessionInputBuffer.java:115)
        at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:92)
        at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:62)
        at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:254)
        at org.apache.http.impl.AbstractHttpClientConnection.receiveResponseHeader(AbstractHttpClientConnection.java:289)
        at org.apache.http.impl.conn.DefaultClientConnection.receiveResponseHeader(DefaultClientConnection.java:252)
        at org.apache.http.impl.conn.ManagedClientConnectionImpl.receiveResponseHeader(ManagedClientConnectionImpl.java:191)
        at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:300)
        at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:127)
        at org.apache.http.impl.client.DefaultRequestDirector.tryExecute(DefaultRequestDirector.java:712)
        at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:517)
        at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)
        at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805)

刚开始以为是超时时间太短,后延长超时时间后问题依旧。

然后更换了httpclient版本。开始使用了httpclient.4.5.6,后觉得时版本问题,更换了4.2.2。问题依旧。换apache cxf web client,spring .RestTemplate还是执行失败

 

令人奇怪的是同样的程序在本地mac,windows机器上调用对方服务正常,部署到我们的服务器上调用对方服务异常。后观察发现对于post小报文正常,报文大于1500左右就异常。后来又自己mock了个服务,调用mock服务正常,即使很大报文也正常返回。

接着使用wireshark抓包工具,抓包发现成功的情况每个ack包都可以收到应答,而失败的情况都会丢失应答,导致服务端返回badrequest(设置sotimeout=0能够收到{"timestamp":"2018-11-27T00:40:47.735+0000","status":400,"error":"Bad

Request","message":"I/O error while reading input message; nested

exception is java.net.SocketTimeoutException","path":""}),发送失败的tcp包长度比较长。

本地wireshark抓包

服务器wireshark抓包

猜测可能是由于tcp太大导致服务器无法接受报文导致失败,于是找到设置该参数的地方SocketConfig.custom().setSndBufSize(1024).在本机测试发现设置后tcp包确实小了

本机wireshark包

部署到服务器上结果该参数没起作用(不知道为什么,后续再分析为什么),抓包后发现跟没有设置setSndBufSize一样的效果

后来只好修改了系统服务器的参数/proc/sys/net/ipv4/tcp_mtu_probing(默认为0)

sudo sysctl -w net.ipv4.tcp_mtu_probing=1或者2.如果设置为1请求响应有明显延迟,如果设置为2请求响应速度相对很快

修改后的wireshark抓包

cat  /proc/sys/net/ipv4/tcp_congestion_control 

cat  /proc/sys/net/ipv4/tcp_available_congestion_control

参考:

http://hc.apache.org/httpcomponents-client-4.5.x/tutorial/html/index.html(翻译可以参考https://blog.csdn.net/chenpeng19910926/article/details/71482347)

http://man7.org/linux/man-pages/man7/tcp.7.html

https://www.jianshu.com/p/dfcca2756aed

https://www.cnblogs.com/ggjucheng/archive/2012/01/14/2322659.html

https://www.linuxidc.com/Linux/2013-07/87309.htm

https://www.cnblogs.com/ppsunlight/p/4000455.html

 sudo tcpdump -AXvvenn  -s 0 'tcp  and  host 139.159.143.73' -w out.cap

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值