项目中经常会需要发送HTTP请求,我这边使用的是apache的 httpClient包,
但是httpClient支持的是同步请求, apache提供了一个 httpasyncClient,基于java NIO
网上看了不少资料,发现写的不是很具体,有点像是小的demo,无法在生产环境运行
而且调用http的execute返回 Futrue<?>类来实现所谓的异步,我更倾向于基于 回调函数的方式
此处代码是基于 httpasyncclient 4.1.3
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpasyncclient</artifactId>
<version>4.1.3</version>
</dependency>
String url="http://www.xxxxx.com";
//此处应该是因为使用的是select模式,利用多核的性质提高并发
IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
.setIoThreadCount(Runtime.getRuntime().availableProcessors())
.build();
RequestConfig config=RequestConfig.custom()
.setConnectionRequestTimeout(20000) // 从连接池获取连接的 timeout
.setConnectTimeout(20000) // 发送http请求 连接目标服务器的timeout
.setSocketTimeout(20000) // 获取目标服务器数据的timeout
.build();
ConnectingIOReactor ioReactor = new DefaultConnectingIOReactor(ioReactorConfig);
PoolingNHttpClientConnectionManager httpConnectionManager = new PoolingNHttpClientConnectionManager(ioReactor);
httpConnectionManager.setMaxTotal(2000);
httpConnectionManager.setDefaultMaxPerRoute(500);
CloseableHttpAsyncClient httpClient = HttpAsyncClients.custom()
.setConnectionManager(httpConnectionManager)
.setDefaultRequestConfig(config).build();
httpClient.start();
HttpGet httpGet = new HttpGet(url);
httpClient.execute(httpGet, new FutureCallback<HttpResponse>() {
@Override
public void completed(HttpResponse httpResponse) {
System.out.println(httpResponse.getStatusLine().getStatusCode());
}
@Override
public void failed(Exception e) {
e.printStackTrace();
}
@Override
public void cancelled(){
System.out.println("connection is closed");
}
});
/**
* 不要关闭 client,close方法会关闭PoolingNHttpClientConnectionManager,导致异步监听器还没
* 收到响应就被关闭了,被这个坑了好久
* 生产环境可以维护这个httpClient不要关闭
*/
//httpClient.close();
ps:
当从连接处从获取连接超时,会抛出 TimeoutException
当连接远程服务器超时,会抛出 ConnectException
当从远程服务器接收数据超时,会抛出 SocketTimeoutException