When using http2 in okhttp, why multi requests to the same host didn't use just one connectoin
Asked Answered
D

1

6

I would like to test okhttp's http2 function. And I make multi requsts to same host in async style. But, I found that, it involved multi connections, since the protocol is h2, It should use just one connection, right? The code is below. Ah, I'm using okhttp2.5

public class Performance {
    private final OkHttpClient client = new OkHttpClient();
    private final Dispatcher dispatcher = new Dispatcher();
    private final int times = 20;

    public Performance(){
        dispatcher.setMaxRequestsPerHost(2);
        client.setDispatcher(dispatcher);

        // Configure the sslContext
        // MySSLSocketFactory mySSLSocketFactory = new MySSLSocketFactory();
        // client.setSslSocketFactory(mySSLSocketFactory);
        // client.setHostnameVerifier(new HostnameVerifier() {
        //     public boolean verify(String s, SSLSession sslSession) {
        //         return true;
        //     }
        // });
    }
    public void run()throws Exception{
        for(int i=0; i<times; i++) {
            Request request = new Request.Builder()
                .url("https://http2bin.org/delay/1")
                .build();
            client.newCall(request).enqueue(new Callback() {
                public void onFailure(Request request, IOException e) {
                    e.printStackTrace();
                }

                public void onResponse(Response response) throws IOException {
                    System.out.println(response.headers().get("OkHttp-Selected-Protocol"));
                }
            });
        }
    }
    public static void main(String[] args)throws Exception{
        Performance performance = new Performance();
        performance.run();
    }
}
Dacha answered 17/9, 2015 at 7:46 Comment(4)
Please explain how do you know that your requests are going through more than one connection.Allomorphism
I get the conclusion for these reasons: 1. when modify dispatcher's maxRequestsPerHost , result changes accordingly, and that's why I use the /delay/1 path for test. The maxRequestsPerHost means the number of connections or just the number of requests, despite that multi requests can be executed in just one connection? ; 2. I compare the performance with HTTP1.1 using other path like /get, it seems that there are no performance differences, no matter how many request I set.Beanstalk
Can you confirm you're getting an HTTP/2 connection? Note that you'll need Jetty-ALPN on the desktop.Roughspoken
Yes, I can. response.headers().get("OkHttp-Selected-Protocol") shows that the protocol used and I got h2. I already add Jetty-ALPN support using -Xbootclasspath/p:C:/Users/zfz/.m2/repository/org/mortbay/jetty/alpn/alpn-boot/8.1.4.v20150727/alpn-boot-8.1.4.v20150727.jar in VM options.Beanstalk
R
1

There's a bug in OkHttp where multiple simultaneous requests each create their own socket connection, rather than coordinating a shared connection. This only happens when the connections are created simultaneously. Work around by yielding 500ms before the 2nd connection.

Roughspoken answered 18/9, 2015 at 2:9 Comment(5)
If this bug exists, it means that in many circumstances my application won't benefit from HTTP/2's multiplexed features, right? Because if I want to wait 500ms to create the 2nd connection, may be using HTTP1.1 is enough. And, I do an experiment by add Thread.sleep(1000) after the client.newCall(reqeust).enqueue, it seems always using multi connections as before.Beanstalk
Is the bug link right? I don't think it's relevant to this problem. Your bug description is related, however, I cannot work around it using sleep. Waiting for your help, thx~Beanstalk
Did they fix this bug in OKHttp3.0+?Howzell
I wanted to know that too. Has this been fixed in 3.x yet?Belding
Actually should be fixed now, though a related issue still needs attention. github.com/square/okhttp/pull/3207Roughspoken

© 2022 - 2024 — McMap. All rights reserved.