OKhttp h2c 协议比 HTTP1.1 协议慢

问题描述 投票:0回答:1

我正在研究是否升级http 2以实现微服务之间的通信。所以我使用okhhtp测试了h2c协议的性能。 但结果很奇怪。 H2c 的性能甚至不如http1.1。我的测试方法或者场景有问题吗?

当并发线程较多时,H2c 的性能会更差。

# 20 thread

http1.1
Benchmark        Mode  Cnt   Score   Error  Units
JMHTest.request  avgt   10  30.997 ± 0.185  ms/op

h2c
Benchmark        Mode  Cnt   Score   Error  Units
JMHTest.request  avgt   10  32.816 ± 1.022  ms/op

# 50 thread

http1.1
Benchmark        Mode  Cnt   Score   Error  Units
JMHTest.request  avgt   10  31.286 ± 0.555  ms/op

h2c
Benchmark        Mode  Cnt   Score   Error  Units
JMHTest.request  avgt   10  72.564 ± 0.678  ms/op

我使用JMH进行测试,我的服务器是启用了HTTP2协议的spring-web服务器。 我期望在使用 okhttp 和 h2c 协议时获得更高的性能。

这是我的测试代码。

环境

  • Jdk:
    openjdk version "17.0.6" 2023-01-17 LTS
  • okhttp3:
    5.0.0-alpha.12

客户

@State(Scope.Benchmark)
public class JMHTest {
    private static final OkHttpClient CLIENT = HttpClientFactory.buildH2PriorClient();
    private static final String URL = "http://localhost:8080/hello";
    private static final Request REQUEST = new Request.Builder()
            .url(URL)
            .post(RequestBody.create(MediaType.get("text/plain"), BodyConstant.BODY_100B))
            .build();

    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                .include(JMHTest.class.getSimpleName())
                .build();

        new Runner(opt).run();
    }

    @BenchmarkMode({Mode.AverageTime})
    @OutputTimeUnit(TimeUnit.MILLISECONDS)
    @Fork(value = 2, warmups = 1)
    @Warmup(iterations = 2)
    @Measurement(iterations = 5)
    @Threads(20)
    @Benchmark
    public void request() {
        post();
    }

    @SneakyThrows
    private void post() {
        Call call = CLIENT.newCall(REQUEST);
        try (Response response = call.execute()) {
            try (ResponseBody body = response.body()) {
                if (!response.isSuccessful()) {
                    throw new RuntimeException();
                }
            }
        }
    }
}
public class HttpClientFactory {

    public static OkHttpClient buildClient() {
        return getClientBuilder().build();
    }

    public static OkHttpClient buildH2PriorClient() {
        OkHttpClient.Builder builder = getClientBuilder();
        builder.setProtocols$okhttp(List.of(Protocol.H2_PRIOR_KNOWLEDGE));
        return builder.build();
    }

    @SneakyThrows
    private static OkHttpClient.Builder getClientBuilder() {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.setReadTimeout$okhttp(3000);
        builder.setConnectTimeout$okhttp(3000);
        builder.setReadTimeout$okhttp(3000);
        builder.setWriteTimeout$okhttp(3000);
        return builder;
    }
}
java http okhttp http2
1个回答
0
投票

HTTP/2 会牺牲少量额外的 CPU 工作量(通常不是 HTTP 调用的瓶颈)来减少创建的 TCP 和 TLS 连接的数量,并减少传输的数据包数量。例如,它使用 HPACK 来压缩标头。

我怀疑,如果您的客户端和服务器在连接上有额外的延迟,并且您限制了客户端同时使用的 TCP 连接数,那么您的基准测试会显示 HTTP/2 是更好的选择。

🎄

© www.soinside.com 2019 - 2024. All rights reserved.