异步请求CloseableHttpAsyncClient的使用

mac2022-06-30  23

1、前言

项目有个需求,需要把一些没用影响业务逻辑的http请求改成异步请求,httpclient在4.0后提供新的api CloseableHttpAsyncClient可以使用,记录下使用过程。

2、网络调用类型

(1)传统BIO(Blocking IO)

同步阻塞式IO,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。

(2)NIO(Not-Blocking IO)

NIO:同步非阻塞式IO,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。

(3)AIO(NIO.2)

异步非阻塞式IO,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理。

3、CloseableHttpAsyncClient

CloseableHttpAsyncClient是apache在4.0后提供AIO操作的api,基本使用如下

1)pom.xml引用如下
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.2</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpcore</artifactId> <version>4.4.5</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpcore-nio</artifactId> <version>4.4.5</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpasyncclient</artifactId> <version>4.1.2</version> </dependency>
2)构造连接
import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.impl.nio.client.CloseableHttpAsyncClient; import org.apache.http.impl.nio.client.HttpAsyncClients; import org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager; import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor; import org.apache.http.impl.nio.reactor.IOReactorConfig; import org.apache.http.nio.reactor.ConnectingIOReactor; import org.apache.http.nio.reactor.IOReactorException; /** * @Title: * @Description:异步连接 * @Author: yangyongzhen * @Date: 2019/9/26 14:38 */ public class AsynHttpClient { private static CloseableHttpAsyncClient client = null; public static CloseableHttpAsyncClient getHttpClient() { if (client == null) { synchronized (AsynHttpClient.class) { if (client == null) { RequestConfig requestConfig = RequestConfig.custom() .setConnectTimeout(2000)//连接超时,连接建立时间,三次握手完成时间 .setSocketTimeout(2000)//请求超时,数据传输过程中数据包之间间隔的最大时间 .setConnectionRequestTimeout(20000)//使用连接池来管理连接,从连接池获取连接的超时时间 .build(); //配置io线程 IOReactorConfig ioReactorConfig = IOReactorConfig.custom(). setIoThreadCount(Runtime.getRuntime().availableProcessors()) .setSoKeepAlive(true) .build(); //设置连接池大小 ConnectingIOReactor ioReactor = null; try { ioReactor = new DefaultConnectingIOReactor(ioReactorConfig); } catch (IOReactorException e) { e.printStackTrace(); } PoolingNHttpClientConnectionManager connManager = new PoolingNHttpClientConnectionManager(ioReactor); connManager.setMaxTotal(5);//最大连接数设置1 connManager.setDefaultMaxPerRoute(5);//per route最大连接数设置 client = HttpAsyncClients.custom() .setConnectionManager(connManager) .setDefaultRequestConfig(requestConfig) .build(); client.start(); } } } return client; } public static HttpPost getPostBody(String urls, String bodys, ContentType contentType) { HttpPost post = null; StringEntity entity = null; post = new HttpPost(urls); entity = new StringEntity(bodys, contentType); post.setEntity(entity); return post; } }

几个重要的参数

ConnectTimeout : 连接超时,连接建立时间,三次握手完成时间。

SocketTimeout : 请求超时,数据传输过程中数据包之间间隔的最大时间。

ConnectionRequestTimeout : 使用连接池来管理连接,从连接池获取连接的超时时间。

ConnTotal:连接池中最大连接数;

ConnPerRoute(1000):分配给同一个route(路由)最大的并发连接数,route为运行环境机器到目标机器的一条线路

3)测试
CloseableHttpAsyncClient httpclient = HttpAsyncClients.createDefault(); CloseableHttpAsyncClient httpClient = AsynHttpClient.getHttpClient(); // String url = "http://www.baidu.com/"; // String url = "https://www.cnblogs.com/"; String url = "https://study.163.com/"; String stringBody = JSONObject.toJSONString(AlarmInfoFrm.getInstanceFrom(alarmInfo)); HttpPost postBody = AsynHttpClient.getPostBody(url, stringBody, ContentType.APPLICATION_JSON); //回调 FutureCallback<HttpResponse> callback = new FutureCallback<HttpResponse>() { @Override public void completed(HttpResponse result) { System.out.println(result.getStatusLine() + "----i:"+i++ ); } @Override public void failed(Exception e) { e.printStackTrace(); System.err.println("失败:"); } @Override public void cancelled() { System.err.println("cancelled"); } }; //连接池执行 httpClient.execute(postBody,callback);

参考的博客和官网地址如下

https://blog.csdn.net/ouyang111222/article/details/78884634 http://hc.apache.org/httpcomponents-asyncclient-4.1.x/quickstart.html

转载于:https://www.cnblogs.com/yz-yang/p/11596844.html

相关资源:JAVA上百实例源码以及开源项目
最新回复(0)