利用JMH基准测试对比不同HTTP客户端(OkHttp vs HttpClient)调用美团API性能
·
利用JMH基准测试对比不同HTTP客户端(OkHttp vs HttpClient)调用美团API性能
在对接美团开放平台等第三方服务时,HTTP 客户端的选型直接影响系统吞吐量与响应延迟。常见的 Java HTTP 客户端包括 Apache HttpClient 与 OkHttp。为科学评估二者在真实场景下的性能差异,本文使用 JMH(Java Microbenchmark Harness) 编写基准测试,模拟高并发下对美团 API 的调用,并给出可复现的代码与结果分析。
引入依赖
首先,在 Maven 项目中添加 JMH、OkHttp 与 Apache HttpClient 依赖:
<dependencies>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>1.37</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>1.37</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.12.0</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>5.2.1</version>
</dependency>
</dependencies>
封装两种客户端的美团 API 调用工具类
为保证测试公平性,统一请求 URL、超时时间与重试策略。
package baodanbao.com.cn.meituan.client;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
public class MeituanApiClient {
private static final String MOCK_API_URL = "https://mock.baodanbao.com.cn/meituan/order/status?orderId=ORD20260113";
// OkHttp 客户端(复用)
private static final OkHttpClient OK_HTTP_CLIENT = new OkHttpClient.Builder()
.connectTimeout(2, TimeUnit.SECONDS)
.readTimeout(3, TimeUnit.SECONDS)
.writeTimeout(3, TimeUnit.SECONDS)
.build();
// Apache HttpClient(复用)
private static final CloseableHttpClient HTTP_CLIENT = HttpClients.custom()
.setConnectionTimeToLive(30, TimeUnit.SECONDS)
.disableAutomaticRetries()
.build();
public static String callWithOkHttp() throws IOException {
Request request = new Request.Builder().url(MOCK_API_URL).build();
try (Response response = OK_HTTP_CLIENT.newCall(request).execute()) {
return response.body() != null ? response.body().string() : "";
}
}
public static String callWithApacheHttpClient() throws IOException {
HttpGet httpGet = new HttpGet(MOCK_API_URL);
httpGet.setConfig(org.apache.hc.client5.http.config.RequestConfig.custom()
.setConnectTimeout(org.apache.hc.core5.util.Timeout.ofSeconds(2))
.setResponseTimeout(org.apache.hc.core5.util.Timeout.ofSeconds(3))
.build());
try (var response = HTTP_CLIENT.execute(httpGet)) {
return EntityUtils.toString(response.getEntity());
}
}
}
注:实际测试中应使用真实美团沙箱环境或本地 Mock Server,确保网络延迟可控。
编写 JMH 基准测试类
使用 @BenchmarkMode、@Fork、@Threads 等注解控制测试行为:
package baodanbao.com.cn.meituan.benchmark;
import baodanbao.com.cn.meituan.client.MeituanApiClient;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.infra.Blackhole;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
@Fork(value = 2, jvmArgs = {"-Xms2g", "-Xmx2g"})
@Threads(16)
@Warmup(iterations = 3, time = 5)
@Measurement(iterations = 5, time = 10)
public class HttpClientsBenchmark {
@Benchmark
public void testOkHttp(Blackhole blackhole) throws IOException {
String result = MeituanApiClient.callWithOkHttp();
blackhole.consume(result);
}
@Benchmark
public void testApacheHttpClient(Blackhole blackhole) throws IOException {
String result = MeituanApiClient.callWithApacheHttpClient();
blackhole.consume(result);
}
public static void main(String[] args) throws RunnerException {
Options options = new OptionsBuilder()
.include(HttpClientsBenchmark.class.getSimpleName())
.build();
new Runner(options).run();
}
}
关键配置说明
@Fork(2):启动两个独立 JVM 进程,避免 JIT 优化干扰。@Threads(16):模拟 16 个并发线程调用,贴近真实高并发场景。@Warmup与@Measurement:预热 3 轮,正式测量 5 轮,每轮持续指定秒数。Blackhole:防止 JVM 优化掉无副作用的返回值。
典型测试结果(示例)
在 8 核 16G Linux 服务器上运行后,可能得到如下输出(单位:毫秒/操作):
Benchmark Mode Cnt Score Error Units
HttpClientsBenchmark.testOkHttp avgt 10 42.35 ± 1.21 ms/op
HttpClientsBenchmark.testApacheHttpClient avgt 10 48.76 ± 1.89 ms/op
结果显示,在相同条件下,OkHttp 平均响应时间比 Apache HttpClient 快约 13%。这主要得益于 OkHttp 内置连接池、高效的 I/O 处理及更轻量的内部结构。
注意事项
- 所有客户端实例必须复用,避免每次创建新连接导致结果失真。
- 测试应避开网络抖动高峰,建议在内网 Mock Server 上进行。
- 若需测试 HTTPS 性能,应启用 TLS 会话复用并配置相同的安全协议版本。
- JMH 默认不捕获异常,若 API 返回 4xx/5xx,需在工具类中处理以避免测试中断。
通过 JMH 可量化评估不同 HTTP 客户端在特定业务场景下的性能表现,为技术选型提供数据支撑。
本文著作权归 俱美开放平台 ,转载请注明出处!
更多推荐




所有评论(0)