ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

java-HttpClient 4静默挂在socketRead上

2019-11-20 02:02:59  阅读:280  来源: 互联网

标签:sockets timeout httpclient java


我有一个应用程序,该应用程序使用Keep-alive连接连续轮询远程HTTP API.

很少但偶尔地,应用程序会在工作一段时间后以静默方式挂起.
套接字仍处于打开状态,但是远程API不返回任何数据.

Httpclient有套接字超时和连接超时,但是如何处理已经连接的超时,套接字仍处于打开状态,但服务器未返回任何数据?

netstat -np用于进程:

Proto Recv-Q Send-Q Local Address               Foreign Address             State       PID/Program name
tcp        0      0 redactedlocalip:31136       redactedforeignip:80        ESTABLISHED 11145/java   

我的httpclient:

SocketConfig socketConfig = SocketConfig.copy(SocketConfig.DEFAULT).setSoTimeout(25000).build();
BasicHttpClientConnectionManager connectionManager = new BasicHttpClientConnectionManager();
connectionManager.setSocketConfig(socketConfig);
return HttpClients
        .custom()
        .setUserAgent(USER_AGENT)
        .setConnectionManager(connectionManager)
        .setRetryHandler(new DefaultHttpRequestRetryHandler())
        .build();

主线程转储:

"main" #11 prio=5 os_prio=0 tid=0x00007f6b802ce800 nid=0x2b9f runnable [0x00007f6b675ec000]
   java.lang.Thread.State: RUNNABLE
        at java.net.SocketInputStream.socketRead0(Native Method)
        at java.net.SocketInputStream.read(SocketInputStream.java:150)
        at java.net.SocketInputStream.read(SocketInputStream.java:121)
        at org.apache.http.impl.io.SessionInputBufferImpl.streamRead(SessionInputBufferImpl.java:139)
        at org.apache.http.impl.io.SessionInputBufferImpl.fillBuffer(SessionInputBufferImpl.java:155)
        at org.apache.http.impl.io.SessionInputBufferImpl.readLine(SessionInputBufferImpl.java:284)
        at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:140)
        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.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)
        at redacted.app.code.executemyRequest(MyClass.java:117)

我正在使用maven的最新版本“ org.apache.httpcomponents:httpclient:4.5”

解决方法:

问题在于行为不佳的HTTP服务器从未响应某些请求,但仍继续保持TCP连接并发送/接收保持活动数据包.
Apache HTTPClient没有内置的超时来处理这些情况,解决方案是在指定的等待时间后手动调用HTTPRequest $abort()方法.
当然,需要从其他线程中调用它,因为调用线程将被阻塞等待.

标签:sockets,timeout,httpclient,java
来源: https://codeday.me/bug/20191120/2040665.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有