F.P*_*F.P 25 java apache-commons-httpclient
我正在开发一个长期运行的应用程序,该应用程序大量使用来自apache的HttpClient.
在我的第一次测试运行中,应用程序运行良好,直到它被卡住.它没有停止,它没有抛出任何异常,只是坐在那里什么都不做.
我刚刚做了第二次跑步并停止了时间,并在大约停止后停止了.24小时不间断运行.此外,我注意到我运行它的笔记本电脑的互联网连接在应用程序卡住的确切时刻终止.我不得不重启我的WLAN适配器,以便再次运行网络.
但是,应用程序在连接再次启动后没有返回工作状态.现在,它又被卡住了.
在HttpClient中是否有任何超时控制器我都不知道?为什么我的应用程序在连接断开时不会抛出异常?
使用客户端的部分如下所示;
public HttpUtil(ConfigUtil config) {
this.config = config;
client = new DefaultHttpClient();
client.getParams().setParameter(HttpProtocolParams.USER_AGENT, this.config.getProperty("httputil.userAgent"));
}
public String getContentAsString(String url) throws ParseException, ClientProtocolException, IOException {
return EntityUtils.toString(
client.execute(
new HttpGet(url)).getEntity());
}
Run Code Online (Sandbox Code Playgroud)
应用程序反复调用httputil.getContentAsString()所需的URL.
Man*_*tel 12
此代码现已弃用(获取HttpParams等).更好的方法是:
RequestConfig defaultRequestConfig = RequestConfig.custom()
.setCookieSpec(CookieSpecs.BEST_MATCH)
.setExpectContinueEnabled(true)
.setStaleConnectionCheckEnabled(true)
.setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM, AuthSchemes.DIGEST))
.setProxyPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC))
.build();
HttpGet httpGet = new HttpGet(url);
RequestConfig requestConfig = RequestConfig.copy(defaultRequestConfig)
.setSocketTimeout(5000)
.setConnectTimeout(5000)
.setConnectionRequestTimeout(5000)
.build();
httpGet.setConfig(requestConfig);
Run Code Online (Sandbox Code Playgroud)
从版本4.4开始,用户user2393012和Stephen C的两个答案都已被弃用.我不确定是否有其他方法可以做到,但我这样做的方法是使用构建器范例HTTPClientBuilder.
防爆.
HttpClients.custom().setConnectionTimeToLive(1, TimeUnit.MINUTES).build()
Run Code Online (Sandbox Code Playgroud)
OP提到的问题也非常类似(实际上可能是OP的问题),但是由于Apache将默认并发连接设置为每个客户端只有两个连接.对此的解决方案是增加最大连接数或关闭它们(如果可以).
要增加最大连接数:
HttpClients.custom().setMaxConnPerRoute(100000).build()
Run Code Online (Sandbox Code Playgroud)
要关闭连接,可以使用BasicHttpClientConnectionManager并调用close方法
您还没有说过您使用的是哪个版本的HttpClient,但假设它是版本4,这篇博客文章解释了该怎么做.
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpParams params = httpClient.getParams();
HttpConnectionParams.setConnectionTimeout(httpParams, connectionTimeoutMillis);
HttpConnectionParams.setSoTimeout(httpParams, socketTimeoutMillis);
Run Code Online (Sandbox Code Playgroud)
我在另一个线程中给出了类似的答案(HttpClient在socketRead0上挂起并成功执行了方法)
在我的例子中,我在请求中设置了connectionTimeout和socketTimeout,但是在建立SSL连接期间没有使用连接套接字.因此,我有时会在SSL握手期间挂起.下面是一些使用v4.4设置所有3个超时的代码(也在v4.5中测试过)
// 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);
Run Code Online (Sandbox Code Playgroud)