我在Java项目中使用apache httpClient库。
不清理HttpClient时出现错误
Timeout waiting for connection
public class RoutingUrlHttpClient implements IRoutingUrlHttpClient {
final static Logger logger = Logger.getLogger(RoutingUrlHttpClient.class);
private IRoutingResponseFromStringFetcher routingResponseParser;
private IRoutingResponseConverter routingResponseConverter;
private IUrlUtils urlUtils;
private CloseableHttpClient client;
private ILogUtils logUtils;
@Inject
@Singleton
public RoutingUrlHttpClient(IRoutingResponseFromStringFetcher routingResponseParser,
IRoutingResponseConverter routingResponseConverter, IUrlUtils urlUtils,
ILogUtils logUtils) {
this.routingResponseParser = routingResponseParser;
this.routingResponseConverter = routingResponseConverter;
this.urlUtils = urlUtils;
this.logUtils = logUtils;
RequestConfig requestConfig = RequestConfig.custom()
//time till handshake
.setConnectTimeout(40 * 1000)
//happens when you have a pool of connections and they are all busy, not allowing the connection
// manager to give you one connection to make the request.
.setConnectionRequestTimeout(40 * 1000)
//time till response
.setSocketTimeout(40 * 1000)
.build();
client = HttpClientBuilder
.create()
.setDefaultRequestConfig(requestConfig)
.build();
}
// public CompleteRoutingResponseDtoWrapper sendAndReturnDtoWrapper(String routingRequestUrl) {
// CompleteRoutingResponseDtoWrapper completeRoutingResponseDtoWrapper = sendRoutingRequestString
// (routingRequestUrl);
// completeRoutingResponseDtoWrapper.requestUrl = routingRequestUrl;
// return completeRoutingResponseDtoWrapper;
// }
@Override
public CompleteRoutingResponseLong sendRoutingRequestStringWithFullResponse(String routingRequestUrl) {
CompleteRoutingResponseDtoWrapper completeRoutingResponseDtoWrapper =
sendRoutingRequestString(routingRequestUrl);
completeRoutingResponseDtoWrapper.requestUrl = routingRequestUrl;
return routingResponseConverter.toCompleteRoutingResponseFull(completeRoutingResponseDtoWrapper);
}
private CompleteRoutingResponseDtoWrapper sendRoutingRequestString(String routingRequestUrl) {
return sendRoutingRequestString(Constants.NUM_OF_RETRIES, routingRequestUrl);
}
private CompleteRoutingResponseDtoWrapper sendRoutingRequestString(int numberOfTriesLeft,
String routingRequestUrl) {
routingRequestUrl = urlUtils.getHttpUrl(routingRequestUrl);
CompleteRoutingResponseDtoWrapper answer = new CompleteRoutingResponseDtoWrapper();
CloseableHttpResponse response = null;
try {
logger.debug("before sending http");
Stopwatch stopWatch = Stopwatch.createStarted();
response = client.execute(new HttpGet(routingRequestUrl));
stopWatch.stop();
// String latencyMsg = "after sending http. client-latency: "+stopWatch.elapsed(TimeUnit.MILLISECONDS) +" server-latency: "+response.getHeaders("Latency")[0].getValue();
logUtils.addLongToLongStatisticCollector("http.client.latency", (int)stopWatch.elapsed(TimeUnit.MILLISECONDS));
logUtils.addLongToLongStatisticCollector("http.server.latency", Integer.parseInt(response.getHeaders("Latency")[0].getValue()));
answer = analyzeStatusCodeAndMsgBody(numberOfTriesLeft, routingRequestUrl, answer, response, stopWatch);
} catch (Exception e) {
// e.printStackTrace();
// System.out.println(e.getMessage());
answer.errorMsg = e.getMessage();
answer.latency = null;
}
handleNullResponse(answer);
return answer;
}
Run Code Online (Sandbox Code Playgroud)
所以我将代码更改为此
@Inject
@Singleton
public RoutingUrlHttpClient(IRoutingResponseFromStringFetcher routingResponseParser,
IRoutingResponseConverter routingResponseConverter, IUrlUtils urlUtils,
ILogUtils logUtils) {
this.routingResponseParser = routingResponseParser;
this.routingResponseConverter = routingResponseConverter;
this.urlUtils = urlUtils;
this.logUtils = logUtils;
requestConfig = RequestConfig.custom()
//time till handshake
.setConnectTimeout(40 * 1000)
//happens when you have a pool of connections and they are all busy, not allowing the connection
// manager to give you one connection to make the request.
.setConnectionRequestTimeout(40 * 1000)
//time till response
.setSocketTimeout(40 * 1000)
.build();
}
// public CompleteRoutingResponseDtoWrapper sendAndReturnDtoWrapper(String routingRequestUrl) {
// CompleteRoutingResponseDtoWrapper completeRoutingResponseDtoWrapper = sendRoutingRequestString
// (routingRequestUrl);
// completeRoutingResponseDtoWrapper.requestUrl = routingRequestUrl;
// return completeRoutingResponseDtoWrapper;
// }
@Override
public CompleteRoutingResponseLong sendRoutingRequestStringWithFullResponse(String routingRequestUrl) {
CompleteRoutingResponseDtoWrapper completeRoutingResponseDtoWrapper =
sendRoutingRequestString(routingRequestUrl);
completeRoutingResponseDtoWrapper.requestUrl = routingRequestUrl;
return routingResponseConverter.toCompleteRoutingResponseFull(completeRoutingResponseDtoWrapper);
}
private CompleteRoutingResponseDtoWrapper sendRoutingRequestString(String routingRequestUrl) {
return sendRoutingRequestString(Constants.NUM_OF_RETRIES, routingRequestUrl);
}
private CompleteRoutingResponseDtoWrapper sendRoutingRequestString(int numberOfTriesLeft,
String routingRequestUrl) {
routingRequestUrl = urlUtils.getHttpUrl(routingRequestUrl);
CompleteRoutingResponseDtoWrapper answer = new CompleteRoutingResponseDtoWrapper();
CloseableHttpResponse response = null;
try {
logger.debug("before sending http");
Stopwatch stopWatch = Stopwatch.createStarted();
//try-with-resources
try (CloseableHttpClient client = HttpClientBuilder
.create()
.setDefaultRequestConfig(requestConfig)
.build()){
response = client.execute(new HttpGet(routingRequestUrl));
stopWatch.stop();
// String latencyMsg = "after sending http. client-latency: "+stopWatch.elapsed(TimeUnit.MILLISECONDS) +" server-latency: "+response.getHeaders("Latency")[0].getValue();
logUtils.addLongToLongStatisticCollector("http.client.latency", (int)stopWatch.elapsed(TimeUnit.MILLISECONDS));
logUtils.addLongToLongStatisticCollector("http.server.latency", Integer.parseInt(response.getHeaders("Latency")[0].getValue()));
answer = analyzeStatusCodeAndMsgBody(numberOfTriesLeft, routingRequestUrl, answer, response, stopWatch);
}
} catch (Exception e) {
// e.printStackTrace();
// System.out.println(e.getMessage());
answer.errorMsg = e.getMessage();
answer.latency = null;
}
handleNullResponse(answer);
return answer;
}
Run Code Online (Sandbox Code Playgroud)
我本来想问:
在每个新请求上初始化一个新的httpClient的好习惯吗?
我是否正确清洁资源?
有没有更有效的发送HTTP请求的方法?也许是nio http client lib?
CloseableHttpClient
是线程安全的,因此您可以安全地重用实例,而不是根据每个请求创建它们。您还可以研究连接池。我经常使用这样的模式:
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
CloseableHttpClient client = HttpClients.custom().setConnectionManager(connectionManager).build();
Run Code Online (Sandbox Code Playgroud)
阅读本文以获取更多背景信息。
归档时间: |
|
查看次数: |
2975 次 |
最近记录: |