Created
March 27, 2018 15:36
-
-
Save smilingleo/cb7c4aa88252bca339c63b02c74178a7 to your computer and use it in GitHub Desktop.
Performance comparison between HTTP/1.1 and HTTP/2 using OkHttpClient
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package leo.me; | |
import okhttp3.Call; | |
import okhttp3.Callback; | |
import okhttp3.OkHttpClient; | |
import okhttp3.Protocol; | |
import okhttp3.Request; | |
import okhttp3.Response; | |
import java.io.IOException; | |
import java.util.Arrays; | |
import java.util.concurrent.TimeUnit; | |
import java.util.concurrent.atomic.AtomicInteger; | |
import java.util.concurrent.atomic.AtomicLong; | |
/** | |
* This class is simply comparing performance of using different versions of HTTP protocols, | |
* HTTP/1.1 and HTTP/2. | |
* | |
* @author Leo Liu | |
* | |
*/ | |
public class HttpProtocolComparison { | |
private static String[] urls = new String[] { | |
"https://nghttp2.org/httpbin/headers", | |
"https://nghttp2.org/httpbin/ip", | |
"https://nghttp2.org/httpbin/user-agent" | |
}; | |
public static void main(String[] args) throws Exception { | |
OkHttpClient h1Client = getHttp1Client(); | |
timer("One KeepAlive Http/1.1", sequentialTest(h1Client)); | |
timer("Pooled KeepAlive Http/1.1", asyncTest(h1Client)); | |
OkHttpClient h2Client = getHttp2Client(); | |
timer("One Sync Mode Http/2", sequentialTest(h2Client)); | |
timer("One Async Mode Http/2", asyncTest(h2Client)); | |
} | |
private static void timer(String scenario, long duration) { | |
System.out.println(String.format("%-30s: %dms\n", scenario, duration)); | |
} | |
private static OkHttpClient getHttp1Client() throws IOException { | |
OkHttpClient client = new OkHttpClient.Builder() | |
.protocols(Arrays.asList(Protocol.HTTP_1_1)) | |
.build(); | |
return client; | |
} | |
private static OkHttpClient getHttp2Client() throws IOException { | |
OkHttpClient client = new OkHttpClient(); | |
return client; | |
} | |
private static long sequentialTest(OkHttpClient client) throws IOException { | |
long begin = System.currentTimeMillis(); | |
for (String url : urls) { | |
if (!testOneUrl(client, url)) { | |
System.out.println("failed for api:" + url); | |
} | |
} | |
long duration = System.currentTimeMillis() - begin; | |
return duration; | |
} | |
private static long asyncTest(OkHttpClient client) throws IOException, InterruptedException { | |
final long begin = System.currentTimeMillis(); | |
final AtomicInteger counter = new AtomicInteger(0); | |
final AtomicLong duration = new AtomicLong(0); | |
for (String url : urls) { | |
Request req = new Request.Builder() | |
.url(url) | |
.build(); | |
client.newCall(req).enqueue(new Callback() { | |
public void onFailure(Call call, IOException e) { | |
System.out.println("call failed"); | |
} | |
public void onResponse(Call call, Response response) throws IOException { | |
printCode(response); | |
if (counter.incrementAndGet() == 3) { | |
duration.set(System.currentTimeMillis() - begin); | |
} | |
} | |
}); | |
} | |
while (duration.get() == 0) { | |
TimeUnit.MILLISECONDS.sleep(10); | |
} | |
return duration.get(); | |
} | |
private static boolean testOneUrl(OkHttpClient client, String url) throws IOException { | |
Request request = new Request.Builder() | |
.url(url) | |
.build(); | |
Response response = client.newCall(request).execute(); | |
printCode(response); | |
return response.code() == 200; | |
} | |
private static void printCode(Response resp) { | |
System.out.println("\t" + resp.code()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment