HttpClient 设置超时问题
Posted devin-wang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HttpClient 设置超时问题相关的知识,希望对你有一定的参考价值。
jps -lvm
jstack -l pid
requestConfig 设置timeout不生效
job出现卡死杜塞情况,查看线程如下
"dcpUpdateOtrAccessTokenCronJob::de.hybris.platform.servicelayer.internal.jalo.ServicelayerJob" prio=5 tid=0x54068 nid=0xd334 RUNNABLE (JNI Native Code) - stats: cpu=344392 blk=-1 wait=-1
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.net.SocketInputStream.read(SocketInputStream.java:171)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at sun.security.ssl.InputRecord.readFully(InputRecord.java:465)
at sun.security.ssl.InputRecord.read(InputRecord.java:503)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:975)
原因:高并发,cpu线程切换频繁,时候会出现SocketInputStream.socketRead0问题
解决方案:
设置httpclien的请求超时时间
代码如下
requestConfig = RequestConfig.custom().setConnectTimeout(CONNECT_TIME_OUT).setConnectionRequestTimeout(CONNECT_TIME_OUT)
.setSocketTimeout(CONNECT_TIME_OUT).setProxy(proxy).build();
这是超时时间之后,发现设置的timeout并不起作用(疑似没有生效),怀疑有重试机制(查资料发现defaultRetryHandle会重试三次),设置retryHandle
private HttpRequestRetryHandler otrRetryHandler = new HttpRequestRetryHandler() {
@Override
public boolean retryRequest(IOException exception,
int executionCount, HttpContext context) {
return false;
}};
CloseableHttpClient httpClient = HttpClients.custom().setRetryHandler(otrRetryHandler).build();(测试没效果,连第三方系统还是挂掉了)
可以设置最大连接数
CloseableHttpClient httpClient = HttpClients.custom().setMaxConnPerRoute(3).setMaxConnTotal(3);
MaxConnPerRoute 分配给同一个route的最大连接数 route是server机器到目标服务器的一条线路 MaxConnTotal连接池最大连接数
譬如使用httpClient分别请求www.baidu.com 和 www.google.com获取资源,就会产生两个route
尝试发现以上方法不可行,现象是获取三方接口时,httpClient会卡死,异常如上,猜想第一次连接目标服务器就被挂起了,没有抛出预想当中的timeout异常
最后,尝试org.apache.commons.httpclient
httpClient也可以设置超时如下
httpClient.getParams().setConnectionManagerTimeout(60000);
httpClient.getParams().setSoTimeout(60000);
这种方式可以正常抛出预想当中的time out异常
INFO | jvm 1 | main | 2018/12/26 20:52:34.118 | java.net.SocketTimeoutException: Read timed out
INFO | jvm 1 | main | 2018/12/26 20:52:34.118 | at java.net.SocketInputStream.socketRead0(Native Method)
INFO | jvm 1 | main | 2018/12/26 20:52:34.118 | at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
INFO | jvm 1 | main | 2018/12/26 20:52:34.118 | at java.net.SocketInputStream.read(SocketInputStream.java:171)
INFO | jvm 1 | main | 2018/12/26 20:52:34.118 | at java.net.SocketInputStream.read(SocketInputStream.java:141)
INFO | jvm 1 | main | 2018/12/26 20:52:34.118 | at sun.security.ssl.InputRecord.readFully(InputRecord.java:465)
INFO | jvm 1 | main | 2018/12/26 20:52:34.118 | at sun.security.ssl.InputRecord.read(InputRecord.java:503)
INFO | jvm 1 | main | 2018/12/26 20:52:34.119 | at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:983)
INFO | jvm 1 | main | 2018/12/26 20:52:34.119 | at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.jav
CloseableHttpClient不能抛出time out异常待验证
以上是关于HttpClient 设置超时问题的主要内容,如果未能解决你的问题,请参考以下文章
Apache HttpClient 4.3 - 设置连接空闲超时
java-commons-HttpClient超时设置setConnectionTimeout和setSoTimeout