Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Long ssl handshake latencies #321

Closed
mvalkon opened this issue Mar 11, 2020 · 6 comments
Closed

Long ssl handshake latencies #321

mvalkon opened this issue Mar 11, 2020 · 6 comments
Labels

Comments

@mvalkon
Copy link

mvalkon commented Mar 11, 2020

This is more of a question than an issue report. How can I debug SSL handshake latencies? Occasionally the handshakes take hundreds of milliseconds, which seems a little bit unreasonable. I am running an aiohttp server which exposes an API, the load is very small, something like 10-20rps load-balanced on 3 instances of the application. Are there any configuration parameters that I can tune? I am not very familiar with the asyncio-internals in python.

Some random examples from logs

<uvloop.loop.SSLProtocol object at 0x7f106f451050>: SSL handshake took 252.0 ms
<uvloop.loop.SSLProtocol object at 0x7f106f4511c0>: SSL handshake took 252.0 ms
<uvloop.loop.SSLProtocol object at 0x7f106f451330>: SSL handshake took 252.0 ms
<uvloop.loop.SSLProtocol object at 0x7f106f4514a0>: SSL handshake took 252.0 ms
<uvloop.loop.SSLProtocol object at 0x7f106f430780>: SSL handshake took 504.0 ms
<uvloop.loop.SSLProtocol object at 0x7f106f430bd0>: SSL handshake took 503.0 ms
<uvloop.loop.SSLProtocol object at 0x7f106f4304a0>: SSL handshake took 509.0 ms
<uvloop.loop.SSLProtocol object at 0x7f106f430a60>: SSL handshake took 508.0 ms
<uvloop.loop.SSLProtocol object at 0x7f106f4308f0>: SSL handshake took 508.0 ms
<uvloop.loop.SSLProtocol object at 0x7f106f430610>: SSL handshake took 509.0 ms
<uvloop.loop.SSLProtocol object at 0x7f106f430eb0>: SSL handshake took 507.0 ms
<uvloop.loop.SSLProtocol object at 0x7f106f430d40>: SSL handshake took 508.0.ms

Here's 10k measurements from the past 24 hours
image

  • uvloop version: 0.14.0
  • Python version: 3.7.6
  • Platform: docker
  • Can you reproduce the bug with PYTHONASYNCIODEBUG in env?:
  • Does uvloop behave differently from vanilla asyncio? How?:
@1st1
Copy link
Member

1st1 commented Mar 11, 2020

@fantix any ideas?

@fantix
Copy link
Member

fantix commented Mar 12, 2020

For a bit more background about SSL handshake - it takes several network round trips to finish. I'm curious how you measured the latency of SSL handshake? Some sample code would be great. I would guess it included the time waiting for clients to respond. So for e.g. mobile devices with the cellular network, it may make sense when the connectivity is unstable.

How can I debug SSL handshake latencies?

I would recommend using a development version of uvloop, add additional logging/statistics in sslproto.pyx at the points where I/O happens. Then it'll be possible to observe the timeline and latency.

Are there any configuration parameters that I can tune?

  • Timeouts. You can set timeouts to prevent long-running SSL handshakes.
  • SSLContext. uvloop uses the built-in SSLContext in Python to handle TLS transport. You could feed uvloop with a customized SSLContext for your need, e.g. selected TLS versions, disablinng features, etc.

@mvalkon
Copy link
Author

mvalkon commented Mar 13, 2020

Thank you @fantix. I did not actually measure specifically the ssl handshake but trusted the logs that uvloop produces when asyncio debug logging is enabled. The graph is an extract of 10k debug log events over a 24-hour period. I'm not sure of the accuracy of this, but it does correlate with higher latencies in my application.

I would guess it included the time waiting for clients to respond

Can you elaborate on what you mean by this? My assumption is that the number produced by the logging represents the complete handshake operation.

  • Timeouts. You can set timeouts to prevent long-running SSL handshakes.
  • SSLContext. uvloop uses the built-in SSLContext in Python to handle TLS transport. You could feed uvloop with a customized SSLContext for your need, e.g. selected TLS versions, disablinng features, etc.

Thanks for this, would you have any pointers to documentation or code where I can start from?

@1st1
Copy link
Member

1st1 commented Mar 17, 2020

This is another area where monitoring APIs (#322) can potentially help us.

@fantix
Copy link
Member

fantix commented Mar 28, 2020

I would guess it included the time waiting for clients to respond

Can you elaborate on what you mean by this? My assumption is that the number produced by the logging represents the complete handshake operation.

Yes. As I mentioned:

SSL handshake takes several network round trips to finish.

This means, before an SSL connection is fully established, several TCP recv/send would happen. And the SSL handshake time recorded in the log starts from the moment TCP connection is made, and ends when SSL handshake succeeds. Therefore, it includes all the network time.

  • Timeouts. You can set timeouts to prevent long-running SSL handshakes.
  • SSLContext. uvloop uses the built-in SSLContext in Python to handle TLS transport. You could feed uvloop with a customized SSLContext for your need, e.g. selected TLS versions, disablinng features, etc.

Thanks for this, would you have any pointers to documentation or code where I can start from?

Please see:

@fantix
Copy link
Member

fantix commented Jan 20, 2021

Closing due to inactivity. Please feel free to reopen if you have further questions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants