Java apache HttpClient出现奇怪的瓶颈(同步和异步)
我试图测试ApacheHTTP客户端库的限制,但遇到了一个奇怪的瓶颈。我的测试包括以下内容:Java apache HttpClient出现奇怪的瓶颈(同步和异步),java,performance,apache-httpclient-4.x,asynchttpclient,Java,Performance,Apache Httpclient 4.x,Asynchttpclient,我试图测试ApacheHTTP客户端库的限制,但遇到了一个奇怪的瓶颈。我的测试包括以下内容: 模拟固定80ms延迟的wiremock服务器 一种单元测试,使用org.apache.http.impl.nio.client.CloseableHttpAsyncClient在收集统计数据的同时,尽可能快地向wiremock服务器发出可配置数量的请求 一种单元测试,它使用org.apache.http.impl.client.CloseableHttpClient,在收集统计数据的同时,从可配置的
org.apache.http.impl.nio.client.CloseableHttpAsyncClient
在收集统计数据的同时,尽可能快地向wiremock服务器发出可配置数量的请求
org.apache.http.impl.client.CloseableHttpClient
,在收集统计数据的同时,从可配置的线程数尽可能快地向wiremock服务器发出可配置数量的请求
org.springframework.web.reactive.function.client.WebClient
在收集统计数据的同时,尽可能快地向wiremock服务器发出可配置数量的请求
- 处理器:3.1 GHz四核Intel Core i7
- 内存:16 GB 2133 MHz LPDDR3
- 操作系统:OSX 10.15.5
- Java版本:11.0.4
package com.blakeparmeter.com;
导入org.apache.http.HttpResponse;
导入org.apache.http.client.methods.CloseableHttpResponse;
导入org.apache.http.client.methods.HttpGet;
导入org.apache.http.concurrent.FutureCallback;
导入org.apache.http.impl.client.CloseableHttpClient;
导入org.apache.http.impl.client.HttpClientBuilder;
导入org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
导入org.apache.http.impl.nio.client.httpacyncClients;
导入org.junit.jupiter.api.Assertions;
导入org.junit.jupiter.api.Test;
导入java.io.IOException;
导入java.net.URI;
导入java.util.concurrent.CountDownLatch;
导入java.util.concurrent.ExecutionException;
导入java.util.concurrent.ForkJoinPool;
导入java.util.stream.IntStream;
/**
*用于说明apache HttpClient的性能瓶颈
*/
公共级瓶颈测试{
//测试变量
最终整数测试=5_000;
最终长消息间隔=1000;//毫秒
最终URI testUri=URI.create(“http://localhost:5000/wait/fixed/empty");
@试验
public void testSync()引发InterruptedException、ExecutionException{
最终int numThreads=100;
//创建同步客户端(测试中的单元)
最终可关闭的HttpClient unitUnderTest=HttpClientBuilder
.create()
.SetMaxConntTotal(5000)
.setMaxConnPerRoute(5000)
.build();
//在执行器上运行测试,将结果发送到统计聚合器
最终ForkJoinPool执行器=新的ForkJoinPool(numThreads);
最终StatsAggregator StatsAggregator=新StatsAggregator(totalTests,messageInterval);
executor.submit(()->IntStream.range(0,numThreads)
.parallel()
.forEach(threadNum->IntStream.range(0,totalTests/numThreads).forEach(testNum->{
最终长时间运行开始=System.currentTimeMillis();
try(final CloseableHttpResponse response=unitUnderTest.execute(new-HttpGet(testUri))){
//我们不需要对响应执行任何操作,只需确保它已发送。
}捕获(最终IOE例外){
断言失败(e);
}
statsAggregator.addTestDuration(System.currentTimeMillis()-runStart);
})))
.get();
//最后一次打印统计数据(因为我们等待执行者,所以不需要等待)
statsAggregator.printStats();
}
@试验
public void testAsync()引发InterruptedException{
//创建异步客户端(正在测试的单元)
最终关闭HttpAsyncClient unitUnderTest=HttpAsyncClients.custom()
.SetMaxConntTotal(5000)
.setMaxConnPerRoute(5000)
.build();
unitUnderTest.start();
//运行所有测试,将结果发送到统计聚合器
最终倒计时闩锁测试倒计时=新倒计时闩锁(totalTests);
最终StatsAggregator StatsAggregator=新StatsAggregator(totalTests,messageInterval);
IntStream.range(0,totalTests).forEach(testNum->{
最终长时间运行开始=System.currentTimeMillis();
execute(新的HttpGet(testUri),新的FutureCallback(){
@凌驾
公共无效完成(最终HttpResponse响应){
statsAggregator.addTestDuration(System.currentTimeMillis()-runStart);
testCountdown.countDown();
}
@凌驾
公共作废失败(最终例外情况除外){
Assertions.fail(例如getMessage());
}
@凌驾
公众假期取消(){
断言失败(“Http请求已取消”);
}
});
});
//等待执行,然后最后打印一次统计数据
testCountdown.wait();
statsAggregator.printStats();
}
@试验
public void testReactive(){
最终WebClient unitUnderTest=WebClient.builder().build();
//运行所有测试,将结果发送到统计聚合器
最终StatsAggregator StatsAggregator=新StatsAggregator(totalTests,messageInterval);
通量范围(0,总测试)
.flatMap(testNum->{
最终长运行启动=系统.current