Manouchehri / serf

High-performance asynchronous HTTP client library
https://code.google.com/p/serf
Apache License 2.0
0 stars 0 forks source link

SSL handshake is slow and inefficient #104

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
SSL connection handshake is very slow compared to other implementation. Even 
for LAN or localhost connection. For example:
> ptime serf_get https://localhost/
Execution time: 0.236 s

Compared to Apache benchmark tool (abs.exe):
> ptime abs https://localhost/
Execution time: 0.168 s

While difference for unencrypted HTTP connection is not so significant:
> ptime serf_get http://localhost/
Execution time: 0.043 s

> ptime ab http://localhost/
Execution time: 0.039 s

Looking to the code it seems that problem that ssl_bucket cannot control 
pollset state and serf context trying to read data from network during 
handshake.

Original issue reported on code.google.com by chemodax@gmail.com on 6 Jun 2013 at 11:09

GoogleCodeExporter commented 9 years ago
I have difficulty reproducing this Ivan, at least on Mac OS X, and connecting 
to a server over the internet.
(serf trunk, release build)

There is the issue of serf busy waiting trying and failing to write when the 
ssl handshake can't continue until data is read. Attached test patch solves 
that issue, using the SERF_ERROR_WAIT_CONN status code already in use for this 
purpose.
While with the patch the total time doesn't improve in my tests, the CPU time 
spent in user mode is reduced drastically.

Original comment by lieven.govaerts@gmail.com on 8 Jun 2013 at 9:21

Attachments:

GoogleCodeExporter commented 9 years ago
Another cause of slowness, is that serf only initialises the ssl context after 
the connection becomes writable. This initialisation can take some time, e.g. 
with svn it takes ~33ms on my laptop, most of the time spent in setting up the 
default root CA certificates.

I've found that we can shave off ~10ms by doing the ssl context initialisation 
during the TCP handshake. So right after creation of the socket we immediately 
start creating all stream buckets, call the application etc., and when the TCP 
handshake is done and the socket becomes writable, serf is read to encrypt data.

Attached updated patch, implementing both the busy loop fix & reordering of ssl 
context initialisation.

Original comment by lieven.govaerts@gmail.com on 9 Jun 2013 at 2:00

Attachments:

GoogleCodeExporter commented 9 years ago
Both v2 and v4 patches doesn't solve reported problem on my Windows 7. It still 
~300 ms for localhost SSL handshake and one HTTP request. 

Original comment by i...@visualsvn.com on 9 Jun 2013 at 3:44

GoogleCodeExporter commented 9 years ago
Hm. I get 330 ms using Subversion+Serf on Mac OS X listing a folder in the asf 
repo:

$ time subversion/svn/svn ls https://svn.apache.org/repos/asf/subversion > 
/tmp/serf2.log 2>&1

real    0m0.331s
user    0m0.038s
sys     0m0.021s

That's down from 340-350 without the patches. What do you see when connecting 
to another server?

Original comment by lieven.govaerts@gmail.com on 9 Jun 2013 at 4:15

GoogleCodeExporter commented 9 years ago
It still slow:
> ptime serf_get.exe https://svn.apache.org/repos/asf/subversion
0.782ms

Original comment by chemodax@gmail.com on 9 Jun 2013 at 4:29

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
Investigated the issue and found the most of the time spend in random generator 
in OpenSSL library. OpenSSL uses CryptoAPI for generating entropy and also it 
scans the *ALL* heaps and processes to gather additional data. It should not be 
needed since CryptoAPI provides secure source for random data since Windows XP.

Original comment by chemodax@gmail.com on 10 Jun 2013 at 11:01

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
Updating label => the major issue here windows specific.
I'll cleanup the 2nd attached patch and apply this to trunk for a minor 
performance improvement on all platforms.

Original comment by lieven.govaerts@gmail.com on 25 Jun 2013 at 5:36

GoogleCodeExporter commented 9 years ago
I've applied patch serf_ssl_busy_loop_v4.patch.txt in r1979 and r1980.

AFAIC, there's nothing more to do for this issue in serf.

Original comment by lieven.govaerts@gmail.com on 2 Jul 2013 at 8:41

GoogleCodeExporter commented 9 years ago
The root cause for reported problem was in slow OpenSSL initialization on 
Windows. But some optimization made in r1979 and r1980, so closing as Fixed.

Original comment by chemodax@gmail.com on 9 Aug 2013 at 4:48