异步httpClient(Async HttpClient)
- 一、简介
- 二、mvn依赖
- 三、客户端
- 3.1 官网实例
- 3.2. 根据官方文档的介绍,简单封装了一个异步HttpClient工具类
- 3.3 基本原理
- 四、参考文档
一、简介
HttpClient提供了两种I/O模型:经典的java阻塞I/O模型和基于Java NIO的异步非阻塞事件驱动I/O模型。
Java中的阻塞I/O是一种高效、便捷的I/O模型,非常适合并发连接数量相对适中的高性能应用程序。只要并发连接的数量在1000个以下并且连接大多忙于传输数据,阻塞I/O模型就可以提供最佳的数据吞吐量性能。然而,对于连接大部分时间保持空闲的应用程序,上下文切换的开销可能会变得很大,这时非阻塞I/O模型可能会提供更好的替代方案。 异步I/O模型可能更适合于比较看重资源高效利用、系统可伸缩性、以及可以同时支持更多HTTP连接的场景。
二、mvn依赖
httpclient在4.x之后开始提供基于nio的异步版本httpasyncclient,httpasyncclient借助了Java并发库和nio进行封装(虽说NIO是同步非阻塞IO,但是HttpAsyncClient提供了回调的机制,与netty类似,所以可以模拟类似于AIO的效果),其调用方式非常便捷.
|
三、客户端
3.1 官网实例
CloseableHttpAsyncClient httpclient = HttpAsyncClients.createDefault(); try { // Start the client httpclient.start(); // Execute request final HttpGet request1 = new HttpGet("http://www.apache.org/"); Future |
3.2. 根据官方文档的介绍,简单封装了一个异步HttpClient工具类
public class AsyncHttpClientUtil { private static final Logger logger = LoggerFactory.getLogger(AsyncHttpClientUtil.class); //从池中获取链接超时时间(ms) private static final int CONNECTION_REQUEST_TIMEOUT = 10000; //建立链接超时时间(ms) private static final int CONNECT_TIMEOUT = 10000; //读取超时时间(ms) private static final int SOCKET_TIMEOUT = 5000; //连接数 private static final int MAX_TOTAL = 50; private static final int MAX_PER_ROUTE = 50; private static final CloseableHttpAsyncClient httpclient; private static PoolingNHttpClientConnectionManager poolManager; static { httpclient=init(); httpclient.start(); } private static CloseableHttpAsyncClient init() { CloseableHttpAsyncClient client=null; try { //配置io线程 IOReactorConfig ioReactorConfig = IOReactorConfig.custom(). setIoThreadCount(Runtime.getRuntime().availableProcessors()) .setSoKeepAlive(true) .build(); //创建一个ioReactor ConnectingIOReactor ioReactor = new DefaultConnectingIOReactor(ioReactorConfig); // poolManager=new PoolingNHttpClientConnectionManager(new DefaultConnectingIOReactor()); poolManager=new PoolingNHttpClientConnectionManager(ioReactor); //设置连接池大小 poolManager.setMaxTotal(MAX_TOTAL); poolManager.setDefaultMaxPerRoute(MAX_PER_ROUTE); // 配置请求的超时设置 RequestConfig requestConfig = RequestConfig.custom() .setConnectionRequestTimeout(CONNECTION_REQUEST_TIMEOUT) .setConnectTimeout(CONNECT_TIMEOUT) .setSocketTimeout(SOCKET_TIMEOUT) .build(); client= HttpAsyncClients.custom() .setConnectionManager(poolManager) .setDefaultRequestConfig(requestConfig) .build(); return client; } catch (IOReactorException e) { e.printStackTrace(); } return client; } public static String get(String url, List |
3.3 基本原理
HTTPAysncClient 最后使用的是 InternalHttpAsyncClient,在 InternalHttpAsyncClient 中有个 ConnectionManager,这个就是我们管理连接的管理器。
而在 httpAsync 中只有一个实现那就是 PoolingNHttpClientConnectionManager。这个连接管理器中有两个我们比较关心的,一个是 Reactor,一个是 Cpool:
- Reactor:所有的 Reactor 这里都是实现了 IOReactor 接口。在 PoolingNHttpClientConnectionManager 中会有拥有一个 Reactor,那就是 DefaultConnectingIOReactor,这个 DefaultConnectingIOReactor,负责处理 Acceptor。
在 DefaultConnectingIOReactor 有个 excutor 方法,生成 IOReactor 也就是我们图中的 BaseIOReactor,进行 IO 的操作。
- CPool:在 PoolingNHttpClientConnectionManager 中有个 CPool,主要是负责控制我们连接,我们上面所说的 maxTotal 和 defaultMaxPerRoute,都是由其进行控制。
如果每个路由有满了,它会断开最老的一个链接;如果总共的 total 满了,它会放入 leased 队列,释放空间的时候就会将其重新连接。
关于Reactor可参考:
四、参考文档
- http://hc.apache.org/httpcomponents-asyncclient-4.1.x/index.html
- http://hc.apache.org/httpcomponents-asyncclient-4.1.x/httpasyncclient/xref/index.html
- http://ifeve.com/httpclient-async-call/
- https://blog.csdn.net/ouyang111222/article/details/78884634