在我们的web应用程序中,用户可以提交一个url。我们将获取数据并在服务器端解析它。对于每个请求,我们使用具有以下(相关)设置的HttpClient
connectionManager.getParams().setConnectionTimeout(10000);
connectionManager.getParams().setSoTimeout(10000);
当我调用HttpMethod。状态码已经被检查为可接受的。此时,线程挂起,堆栈跟踪如下:
java.net.SocketInputStream.socketRead0 ( native code )
java.net.SocketInputStream.read ( SocketInputStream.java:150 )
java.net.SocketInputStream.read ( SocketInputStream.java:121 )
java.io.BufferedInputStream.read1 ( BufferedInputStream.java:273 )
java.io.BufferedInputStream.read ( BufferedInputStream.java:334 )
java.io.FilterInputStream.read ( FilterInputStream.java:133 )
org.apache.commons.httpclient.AutoCloseInputStream.read ( AutoCloseInputStream.java:108 )
java.io.FilterInputStream.read ( FilterInputStream.java:107 )
org.apache.commons.httpclient.AutoCloseInputStream.read ( AutoCloseInputStream.java:127 )
org.apache.commons.httpclient.HttpMethodBase.getResponseBody ( HttpMethodBase.java:690 )
我无法发现发生此事件的确切URL(是实时环境中的事件),并且我无法复制它。我想这只是我们连接的服务器行为奇怪的问题,但也许我遗漏了什么。在任何一种情况下,是否有一种方法可以防止阻塞方法调用永远等待?SoTimeout也是套接字读取超时?还有别的场景我没看到吗?
我有所有的超时设置很好,但我发现我们有一个url,做http分块,但没有发送结果(在chrome中工作很好,但在http客户端它永远挂着,即使超时设置)。幸运的是,我拥有的服务器,只是返回一些垃圾,它不再挂起。这似乎是一个非常独特的错误,在http客户端不能很好地处理某种空块情况(尽管我可能是方式)....我只知道它每次都挂在同一个url上,空数据url是http chunking csv下载回我们的http客户端
HttpClient区分连接和请求。setSoTimeout
将配置连接套接字超时,而setConnectionTimeout
将配置连接管理器的超时(等待连接的时间)和连接本身建立的超时。在您提供的代码中,您没有为用于请求本身的套接字设置任何超时,不幸的是,HttpClient默认没有超时。
在v4.4.1中我是这样做的:
// Configure the socket timeout for the connection, incl. ssl tunneling
connManager = new PoolingHttpClientConnectionManager();
connManager.setMaxTotal(200);
connManager.setDefaultMaxPerRoute(100);
SocketConfig sc = SocketConfig.custom()
.setSoTimeout(soTimeoutMs)
.build();
connManager.setDefaultSocketConfig(sc);
HttpClient client = HttpClients.custom()
.setConnectionManager(connManager)
.setConnectionManagerShared(true)
.build();
// configure the timeouts (socket and connection) for the request
RequestConfig.Builder config = = RequestConfig.copy(RequestConfig.DEFAULT);
config.setConnectionRequestTimeout(connectionTimeoutMs);
config.setSocketTimeout(socketTimeoutMs);
HttpRequestBase req = new HttpGet(uri);
req.setConfig(config.build());
client.execute(req);
当我调用HttpMethod。状态码已经被检查为可接受的。此时,线程挂起
看起来你在同步呼叫方面有问题…您应该确保方法
HttpMethod。getResponseBody
是顺序调用的,或者应该为改变状态码的部分使用互斥锁(信号量)
你还应该减少超时限制,以防止挂起
我们在我们的实现中一直看到这种情况,看起来http客户端没有正确处理坏服务器或其他东西,并且没有超时.....我可以在我们的设置中复制这个databus开源项目,堆栈跟踪有点不同…
SocketInputStream。socketRead0(FileDescriptor, byte[], int, int, int) line: not available [native method]
SocketInputStream。Read (byte[], int, int) line: 129
SocketInputBuffer(AbstractSessionInputBuffer).fillBuffer() line: 166
SocketInputBuffer.fillBuffer() line: 90SocketInputBuffer(AbstractSessionInputBuffer).readLine(CharArrayBuffer) line: 281
DefaultHttpResponseParser.parseHead(SessionInputBuffer) line: 92
DefaultHttpResponseParser.parseHead(SessionInputBuffer) line: 62
DefaultHttpResponseParser(AbstractMessageParser).parse() line: 254
DefaultClientConnection(AbstractHttpClientConnection).receiveResponseHeader() line: 289DefaultClientConnection.receiveResponseHeader() line: 252
BasicPooledConnAdapter(AbstractClientConnAdapter).receiveResponseHeader() line: 219HttpRequestExecutor。doreceiverresponse (HttpRequest, HttpClientConnection, HttpContext) line: 300HttpRequestExecutor。execute(HttpRequest, HttpClientConnection, HttpContext) line: 127
DefaultRequestDirector。tryExecute(RoutedRequest, HttpContext) line: 712DefaultRequestDirector。execute(HttpHost, HttpRequest, HttpContext) line: 517
DefaultHttpClient (AbstractHttpClient)。execute(HttpHost, HttpRequest, HttpContext) line: 906DefaultHttpClient (AbstractHttpClient)。execute(HttpUriRequest, HttpContext) line: 805
ReadAggregations。processAggregation(String, Counter, Counter, Counter, Counter, Counter) line: 153
ReadAggregations.start() line: 96
ReadAggregations.main(String[]) line: 70
您可以尝试使用httpurirequest# abort()中止请求,参见https://hc.apache.org/httpcomponents-client-4.3.x/httpclient/apidocs/org/apache/http/client/methods/HttpUriRequest.html#abort%28%29。然而,设置一个不需要拦截的超时会更好。这里有一个相关的问题:在apache http客户端设置超时