Java:支持异步回调的HTTP客户端开源组件

目录

一、Reactor Netty

二、 Apache HttpAsyncClient

三、AsyncHttpClient

四、Grizzly Async Http Client

五、OkHttp


       当程序需要连接多个服务器端,或与同一个服务器端进行频繁交互时,使用异步HTTP客户端会极大的提高程序处理的吞吐量。

当前比较流行的支持回调的异步HTTP客户端:

一、Reactor Netty

Reactor Netty Reference Guide
基于Netty,实现reactive streams,支持WebSocket

<dependency>
	<groupId>io.projectreactor.netty</groupId>
	<artifactId>reactor-netty-http</artifactId>
	<version>1.0.32</version>
</dependency>

连接池配置:

ConnectionProvider.create("connMgr", 4)

线程池配置:

LoopResources.create("reactor-", 4, false) 或 -Dreactor.netty.ioWorkerCount

默认线程数:

Runtime.getRuntime().availableProcessors()

 示例:

final CountDownLatch latch1 = new CountDownLatch(1);

ConnectionProvider connectionProvider = ConnectionProvider.builder("custom") //
		.maxConnections(50)//
		.maxIdleTime(Duration.ofSeconds(20)) //
		.maxLifeTime(Duration.ofSeconds(60))//
		.pendingAcquireTimeout(Duration.ofSeconds(60)) //
		.evictInBackground(Duration.ofSeconds(120))//
		.metrics(true)//
		.build();

HttpClient client = HttpClient.create(connectionProvider) // 设置连接数
		.runOn(LoopResources.create("reactor-", 4, false)); // 设置线程数

client.get().uri("https://www.apache.org").responseContent().aggregate().asString().subscribe(s -> {
	System.out.println(Thread.currentThread().getName());
	System.out.println(s);

	latch1.countDown();
});
latch1.await();

二、 Apache HttpAsyncClient

Apache HttpComponents – HttpAsyncClient Overview

<dependency>
	<groupId>org.apache.httpcomponents</groupId>
	<artifactId>httpasyncclient</artifactId>
	<version>4.1.5</version>
</dependency>

 一个用于发送http请求的线程,线程名

Thread[pool-1-thread-1]

多个用于处理http响应的线程,线程名

Thread[I/O dispatcher i]

默认线程数由Runtime.getRuntime().availableProcessors()确定,可通过如下方式配置自定义线程数

IOReactorConfig.Builder.setDefaultMaxIoThreadCount(int);

 示例:

IOReactorConfig.Builder builder = IOReactorConfig.custom();
builder.setIoThreadCount(3); // 设置线程数
IOReactorConfig ioReactorConfig = builder.build();

PoolingNHttpClientConnectionManager connectionManager = new PoolingNHttpClientConnectionManager(
		new DefaultConnectingIOReactor(ioReactorConfig));
connectionManager.setMaxTotal(200); // 设置最大连接数
connectionManager.setDefaultMaxPerRoute(50); // 设置每个路由的最大连接数

HttpAsyncClientBuilder httpAsyncClientBuilder = HttpAsyncClients.custom();
httpAsyncClientBuilder.useSystemProperties() //
		.setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy()) //
		.setConnectionManager(connectionManager);

CloseableHttpAsyncClient httpclient = httpAsyncClientBuilder.build();
try {
	// Start the client
	httpclient.start();

	// One most likely would want to use a callback for operation result
	final CountDownLatch latch1 = new CountDownLatch(1);
	final HttpGet request2 = new HttpGet("https://www.apache.org/");
	httpclient.execute(request2, new FutureCallback<HttpResponse>() {

		public void completed(final HttpResponse response2) {
			System.out.println(Thread.currentThread().getName() + ":completed");
			latch1.countDown();
			System.out.println(request2.getRequestLine() + "->" + response2.getStatusLine());
		}

		public void failed(final Exception ex) {
			System.out.println(Thread.currentThread().getName() + ":failed");
			latch1.countDown();
			System.out.println(request2.getRequestLine() + "->" + ex);
		}

		public void cancelled() {
			System.out.println(Thread.currentThread().getName() + ":cancelled");
			latch1.countDown();
			System.out.println(request2.getRequestLine() + " cancelled");
		}

	});
	latch1.await();

} finally {
	httpclient.close();
}

三、AsyncHttpClient

https://github.com/AsyncHttpClient/async-http-client
基于Netty,实现reactive streams,支持WebSocket
参考文档:
Asynchronous HTTP with async-http-client in Java | Baeldung

<dependency>
	<groupId>org.asynchttpclient</groupId>
	<artifactId>async-http-client</artifactId>
	<version>2.12.3</version>
</dependency>

 默认线程数

-Dorg.asynchttpclient.ioThreadsCount

默认最大连接数

-Dorg.asynchttpclient.maxConnections

线程名

AsyncHttpClient-timer-1-1

AsyncHttpClient-3-1

 示例:

final CountDownLatch latch1 = new CountDownLatch(1);

DefaultAsyncHttpClientConfig.Builder builder = new DefaultAsyncHttpClientConfig.Builder();
DefaultAsyncHttpClientConfig config = builder.setMaxConnections(200) //
		.setIoThreadsCount(10) //
		.setKeepAlive(true) //
		.build();

try (AsyncHttpClient asyncHttpClient = new DefaultAsyncHttpClient(config);) {
	ListenableFuture<Response> whenResponse = asyncHttpClient.prepareGet("https://www.apache.org/").execute();

	Runnable callback = () -> {
		try {
			Response response = whenResponse.get();
			System.out.println(response);
			latch1.countDown();
		} catch (InterruptedException | ExecutionException e) {
			e.printStackTrace();
		}
	};

	//Executor executor = Executors.newSingleThreadExecutor();
	whenResponse.addListener(callback, null);
	
	latch1.await();
}

四、Grizzly Async Http Client

https://github.com/javaee/grizzly-ahc
https://github.com/eclipse-ee4j/grizzly-ahc

<dependency>
	<groupId>org.glassfish.grizzly</groupId>
	<artifactId>grizzly-http-client</artifactId>
	<version>1.15</version>
</dependency>

selector线程数:

Runtime.getRuntime().availableProcessors() > 5 ? Runtime.getRuntime().availableProcessors() : 5;

线程名:

grizzly-ahc-kernel(i) SelectorRunner

callback线程池可指定

示例:

final CountDownLatch latch1 = new CountDownLatch(1);

AsyncHttpClientConfig.Builder builder = new AsyncHttpClientConfig.Builder();
builder.setAllowPoolingConnections(true) //
		.setMaxConnections(200) //
		.setIOThreadMultiplier(0) //
		.setExecutorService(Executors.newSingleThreadScheduledExecutor());

AsyncHttpClient asyncHttpClient = new AsyncHttpClient(builder.build());
asyncHttpClient.prepareGet("https://www.apache.org/").execute(new AsyncCompletionHandler<Response>() {

	@Override
	public Response onCompleted(Response response) throws Exception {
		String body = response.getResponseBody();
		System.out.println(body);

		latch1.countDown();

		return response;
	}

	@Override
	public void onThrowable(Throwable t) {
		// Something wrong happened.
	}
});

latch1.await();

五、OkHttp

GitHub - square/okhttp: Square’s meticulous HTTP client for the JVM, Android, and GraalVM.

<dependency>
	<groupId>com.squareup.okhttp3</groupId>
	<artifactId>okhttp</artifactId>
	<version>4.11.0</version>
</dependency>

回调线程都是临时创建的

示例:

OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.connectionPool(new ConnectionPool(10, 60, TimeUnit.SECONDS));
OkHttpClient client = builder.build();

String url = "https://www.apache.org/";
Request request = new Request.Builder().url(url).build();

final CountDownLatch latch1 = new CountDownLatch(1);

client.newCall(request).enqueue(new Callback() {

	@Override
	public void onFailure(Call arg0, IOException arg1) {

	}

	@Override
	public void onResponse(Call arg0, Response response) throws IOException {
		String body = response.body().string();

		System.out.println(body);

		latch1.countDown();
	}
});

latch1.await();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值