Skip to content
master
Go to file
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
 
 
 
 
 
 

README.md

VariousAsyncHttpClientPerformance

Scenario:

10*1000 total requests, 1000 concurrency, server block every request for 10 seconds.

Compare AsyncRestTemplate combined with 4 different AsyncRequestFactory.

Conclusion

If you just want send several requests, default and okhttp is both ok.

If you want to handle thousands of slow connections simultaneously, you should use CloseableHttpAsyncClient or Netty4.

If you also want to use proxy, then only CloseableHttpAsyncClient is avaiable.

Implementation

SimpleClientHttpRequestFactory

AsyncRestTemplate's default request factory SimpleClientHttpRequestFactory, use a simple thread pool and blocking api, so it will use 1000 threads to handle 1000 concurrency.

It take 101.702 seconds, close to 100 seconds.

Thread stack follows behind:

"SimpleAsyncTaskExecutor-1001" #1015 prio=5 os_prio=31 tid=0x00007fc9d8949800 nid=0x82d03 runnable [0x000070004e716000]
   java.lang.Thread.State: RUNNABLE
	at java.net.SocketInputStream.socketRead0(Native Method)
	at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
	at java.net.SocketInputStream.read(SocketInputStream.java:170)
	at java.net.SocketInputStream.read(SocketInputStream.java:141)
	at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
	at java.io.BufferedInputStream.read1(BufferedInputStream.java:286)
	at java.io.BufferedInputStream.read(BufferedInputStream.java:345)
	- locked <0x0000000773843bb8> (a java.io.BufferedInputStream)
	at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:704)
	at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:647)
	at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1535)
	- locked <0x00000006c2f84e38> (a sun.net.www.protocol.http.HttpURLConnection)
	at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1440)
	- locked <0x00000006c2f84e38> (a sun.net.www.protocol.http.HttpURLConnection)
	at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480)
	at org.springframework.http.client.SimpleBufferingAsyncClientHttpRequest$1.call(SimpleBufferingAsyncClientHttpRequest.java:94)
	at org.springframework.http.client.SimpleBufferingAsyncClientHttpRequest$1.call(SimpleBufferingAsyncClientHttpRequest.java:77)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.lang.Thread.run(Thread.java:745)

Okhttp3

OkHttp3ClientHttpRequestFactory also use blocking thread pool, 1000 threads to handle 1000 concurrency.

It takes 101.697 seconds, close to 100 seconds.

Thread stack follows behind:

"OkHttp http://127.0.0.1:8080/..." #1018 prio=5 os_prio=31 tid=0x00007fa803526000 nid=0x83103 runnable [0x000070004f9ec000]
   java.lang.Thread.State: RUNNABLE
	at java.net.SocketInputStream.socketRead0(Native Method)
	at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
	at java.net.SocketInputStream.read(SocketInputStream.java:170)
	at java.net.SocketInputStream.read(SocketInputStream.java:141)
	at okio.Okio$2.read(Okio.java:138)
	at okio.AsyncTimeout$2.read(AsyncTimeout.java:238)
	at okio.RealBufferedSource.indexOf(RealBufferedSource.java:325)
	at okio.RealBufferedSource.indexOf(RealBufferedSource.java:314)
	at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:210)
	at okhttp3.internal.http.Http1xStream.readResponse(Http1xStream.java:186)
	at okhttp3.internal.http.Http1xStream.readResponseHeaders(Http1xStream.java:127)
	at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.java:53)
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
	at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:45)
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
	at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:109)
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
	at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
	at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:124)
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
	at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:170)
	at okhttp3.RealCall.access$100(RealCall.java:33)
	at okhttp3.RealCall$AsyncCall.execute(RealCall.java:120)
	at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)

CloseableHttpAsyncClient

When using CloseableHttpAsyncClient, it only cost 8 threads to handle 1000 concurrency.

It takes 101.103 seconds, close to 100 seconds.

Thread stack follows behind, indeed nio select:

"I/O dispatcher 8" #24 prio=5 os_prio=31 tid=0x00007fd54f0f2000 nid=0x6f03 runnable [0x000070000ba7e000]
   java.lang.Thread.State: RUNNABLE
	at sun.nio.ch.KQueueArrayWrapper.kevent0(Native Method)
	at sun.nio.ch.KQueueArrayWrapper.poll(KQueueArrayWrapper.java:198)
	at sun.nio.ch.KQueueSelectorImpl.doSelect(KQueueSelectorImpl.java:103)
	at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
	- locked <0x000000076b0cc5b8> (a sun.nio.ch.Util$2)
	- locked <0x000000076b0cc5a8> (a java.util.Collections$UnmodifiableSet)
	- locked <0x000000076b0cc488> (a sun.nio.ch.KQueueSelectorImpl)
	at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
	at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:255)
	at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:104)
	at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:588)
	at java.lang.Thread.run(Thread.java:745)

Netty4

When using Netty4ClientHttpRequestFactory, it cost 16 threads to handle 1000 concurrency.

It takes 100.892 seconds, close to 100 seconds.

Thread stack follows behind, indeed nio select:

"nioEventLoopGroup-2-16" #29 prio=10 os_prio=31 tid=0x00007fdd33232000 nid=0x7903 runnable [0x000070000e941000]
   java.lang.Thread.State: RUNNABLE
	at sun.nio.ch.KQueueArrayWrapper.kevent0(Native Method)
	at sun.nio.ch.KQueueArrayWrapper.poll(KQueueArrayWrapper.java:198)
	at sun.nio.ch.KQueueSelectorImpl.doSelect(KQueueSelectorImpl.java:103)
	at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
	- locked <0x000000076f5b01f8> (a io.netty.channel.nio.SelectedSelectionKeySet)
	- locked <0x000000076f5b0218> (a java.util.Collections$UnmodifiableSet)
	- locked <0x000000076f5b01a8> (a sun.nio.ch.KQueueSelectorImpl)
	at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
	at io.netty.channel.nio.NioEventLoop.select(NioEventLoop.java:759)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:400)
	at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:873)
	at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144)
	at java.lang.Thread.run(Thread.java:745)

About

No description, website, or topics provided.

Resources

Releases

No releases published

Packages

No packages published

Languages

You can’t perform that action at this time.