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

How to warm up SslConnection #6514

Closed
dwen77 opened this issue Jul 12, 2021 · 11 comments · Fixed by #12151
Closed

How to warm up SslConnection #6514

dwen77 opened this issue Jul 12, 2021 · 11 comments · Fixed by #12151
Assignees

Comments

@dwen77
Copy link

dwen77 commented Jul 12, 2021

Jetty version
org.eclipse.jetty:jetty-client:9.4.36.v20210114
Java version
openjdk version "11.0.2" 2019-01-15
Question
Hi Community,

It is a follow up question of a question that I raised earlier. I tried to use preCreateConnections and resolveDestination to pre create connections in connection pool. The time that is spent on obtaining connections has been reduced significantly. However, my original goal is to warm up connections before sending any request so that the time which is spent on SSL handshake can be eliminated for the first request.

However, after profiling my application, I found that the call to wrap method of class SslConnection still occurs when making the first request. Please see the attached flame graph below.

I am wondering if it is possible to warm up the SslConnection even before sending the first request? Any suggestions would be greatly appreciated!

flamegraph

@sbordet
Copy link
Contributor

sbordet commented Jul 12, 2021

Just to be clear, method wrap() is always called, both during the TLS handshake, but also when encrypting data after the TLS handshake.

However, yes, we don't have a way to force the TLS handshake, which is always initiated lazily when the first request is sent.
Typically this is not an issue because the cost is amortized among many requests on that connection, but I can see how having an option for eagerly initiate the TLS handshake may be desirable.

@dwen77
Copy link
Author

dwen77 commented Jul 12, 2021

Hi @sbordet , thanks for the clarification and hopefully the feature can be supported officially!

In my application, there is a class implements the interface Request.Listener in order to record the time spent on each step.

What I observed is that between invoking onBegin and onSuccess, the first request took 100ms+ more than the subsequent requests (the time spent is almost 0ms) , moreover, I compared two threads that send first request and second request and found the SSLHandshake only occurs in the first thread. Therefore, I drew a conclusion that sending first request triggers the SSLHandshake which adds extra time.

Do you think it could be a workaround to avoid SSL handshake when sending the first request if application sends a dummy request to the same destination before it started? Maybe it is a bit tricky as a single request can only trigger SSL handshake of one connection in the connection pool.

@sbordet
Copy link
Contributor

sbordet commented Jul 12, 2021

Do you think it could be a workaround to avoid SSL handshake when sending the first request if application sends a dummy request to the same destination before it started? Maybe it is a bit tricky as a single request can only trigger SSL handshake of one connection in the connection pool.

Yes that will work the problem around by "priming" the connection and forcing the TLS handshake.

@dwen77
Copy link
Author

dwen77 commented Jul 12, 2021

Hi @sbordet ! Do you think the solution even works if application sends concurrent requests sent as soon as it is started? I thought concurrent requests may need to use multiple connections from connection pool and the dummy request cannot force TLS handshake of all these connections. Is my understanding correct?

@sbordet
Copy link
Contributor

sbordet commented Jul 13, 2021

Yes you would need to force the TLS handshake on all connections.
That is a bit tricky but doable with a request begin listener that sends the 2nd, then the 3rd, etc. in a blocking way.

Consider whether this is worth the effort. Lots of complexity for 100 ms that are amortized.

@dwen77
Copy link
Author

dwen77 commented Jul 13, 2021

Hi @sbordet , thanks for the explanation! As the logic will become quite complicated, I will try to just send a single dummy request to force handshake of a single connection and see if the application could gain any performance.

@github-actions
Copy link

This issue has been automatically marked as stale because it has been a
full year without activity. It will be closed if no further activity occurs.
Thank you for your contributions.

@github-actions github-actions bot added the Stale For auto-closed stale issues and pull requests label Jul 14, 2022
@sbordet sbordet removed the Stale For auto-closed stale issues and pull requests label Jul 14, 2022
@github-actions
Copy link

This issue has been automatically marked as stale because it has been a
full year without activity. It will be closed if no further activity occurs.
Thank you for your contributions.

@github-actions github-actions bot added the Stale For auto-closed stale issues and pull requests label Jul 15, 2023
@sbordet sbordet removed the Stale For auto-closed stale issues and pull requests label Jul 15, 2023
Copy link

This issue has been automatically marked as stale because it has been a
full year without activity. It will be closed if no further activity occurs.
Thank you for your contributions.

@github-actions github-actions bot added the Stale For auto-closed stale issues and pull requests label Jul 15, 2024
@gregw
Copy link
Contributor

gregw commented Jul 15, 2024

@sbordet I think we can close this one?

@github-actions github-actions bot removed the Stale For auto-closed stale issues and pull requests label Jul 16, 2024
@sbordet
Copy link
Contributor

sbordet commented Aug 7, 2024

@gregw let me ponder about this for a little more, as it may be an important use case also for customers.

@sbordet sbordet self-assigned this Aug 7, 2024
sbordet added a commit that referenced this issue Aug 8, 2024
Implemented "priming" of HTTP/1.1 connections using ConnectionPool.preCreateConnections(int) and HttpClientTransportOverHTTP.setInitializeConnections(true).

This sends `OPTIONS * HTTP/1.1` to the server.

I tried to implement this feature by forcing a write of 0 bytes from the layer above `SslConnection`, but it did not work when using TLS because in both WriteFlusher and SslConnection the fact that there are 0 bytes left to write is treated specially.

Other HTTP versions have no problems because they must initialize the connection by e.g. sending a SETTINGS frame, so they would also initialize TLS.

Signed-off-by: Simone Bordet <[email protected]>
@sbordet sbordet linked a pull request Aug 8, 2024 that will close this issue
@sbordet sbordet moved this to 🏗 In progress in Jetty 12.0.13 - FROZEN Aug 14, 2024
@github-project-automation github-project-automation bot moved this from 🏗 In progress to ✅ Done in Jetty 12.0.13 - FROZEN Aug 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
Status: ✅ Done
Development

Successfully merging a pull request may close this issue.

3 participants