[jdk17u-dev] RFR: 8298381: Improve handling of session tickets for multiple SSLContexts

David Schlosnagle duke at openjdk.org
Mon Jul 29 18:05:43 UTC 2024


On Mon, 29 Jul 2024 17:54:17 GMT, David Schlosnagle <duke at openjdk.org> wrote:

> I would like to propose a backport of [JDK-8298381](https://bugs.openjdk.org/browse/JDK-8298381) commit https://github.com/openjdk/jdk/commit/debe5879aa7118a114ff6fcf8d15951757ae70a8 that landed in JDK 21 to jdk17u. This change significantly improves TLS handshaking latency and throughput for services that utilize multiple `SSLContext`. As an example, Apache Kafka running on JDK 17 with significant numbers of clients may see over 40% of CPU utilization due to `SessionTicketExtension$KeyState.cleanup(HandshakeContext)`.
> 
> @simonis or others, would you be willing to sponsor this change to JDK 17u and create a corresponding JIRA ticket?
> 
> Thanks!

As an example, Apache Kafka running on JDK 17 with significant numbers of clients may see over 40% of CPU utilization due to `SessionTicketExtension$KeyState.cleanup(HandshakeContext)` as seen in JFR snippets from an example environment. Upgrading to JDK 21 does resolve this as expected; however, there are some systems that may not be able to immediately upgrade to JDK 21 or later that would benefit from this change.

![image](https://github.com/user-attachments/assets/e3123386-0825-41fa-bd3a-de5c0a9ca905)
![image](https://github.com/user-attachments/assets/29f23e95-b8f8-496b-abe2-f3d17223452b)


The most sampled method was void sun.security.ssl.SessionTicketExtension$KeyState.cleanup(HandshakeContext), with 4.33 % of the maximum possible samples for 7/27/2024, 3:19:48.000 PM – 3:20:18 PM, and 46.9 % of the actual samples.
The methods that used the most CPU are:
sun.security.ssl.SessionTicketExtension$KeyState.cleanup(HandshakeContext) (46.9 % of samples) 7/27/2024, 3:19:48.000 PM – 3:20:18 PM

The most common stack trace was:
  at void sun.security.ssl.SessionTicketExtension$KeyState.cleanup(sun.security.ssl.HandshakeContext)
  at sun.security.ssl.SessionTicketExtension$StatelessKey sun.security.ssl.SessionTicketExtension$KeyState.nextKey(sun.security.ssl.HandshakeContext)
  at sun.security.ssl.SessionTicketExtension$StatelessKey sun.security.ssl.SessionTicketExtension$KeyState.getCurrentKey(sun.security.ssl.HandshakeContext)
  at byte[] sun.security.ssl.SessionTicketExtension$SessionTicketSpec.encrypt(sun.security.ssl.HandshakeContext, sun.security.ssl.SSLSessionImpl)
  at byte[] sun.security.ssl.NewSessionTicket$T12NewSessionTicketProducer.produce(sun.security.ssl.ConnectionContext, sun.security.ssl.SSLHandshake$HandshakeMessage)
  at byte[] sun.security.ssl.Finished$T12FinishedProducer.onProduceFinished(sun.security.ssl.ServerHandshakeContext, sun.security.ssl.SSLHandshake$HandshakeMessage)
  at byte[] sun.security.ssl.Finished$T12FinishedProducer.produce(sun.security.ssl.ConnectionContext, sun.security.ssl.SSLHandshake$HandshakeMessage)
  at byte[] sun.security.ssl.SSLHandshake.produce(sun.security.ssl.ConnectionContext, sun.security.ssl.SSLHandshake$HandshakeMessage)
  at void sun.security.ssl.Finished$T12FinishedConsumer.onConsumeFinished(sun.security.ssl.ServerHandshakeContext, java.nio.ByteBuffer)
  at void sun.security.ssl.Finished$T12FinishedConsumer.consume(sun.security.ssl.ConnectionContext, java.nio.ByteBuffer)
  at void sun.security.ssl.SSLHandshake.consume(sun.security.ssl.ConnectionContext, java.nio.ByteBuffer)
  at void sun.security.ssl.HandshakeContext.dispatch(byte, java.nio.ByteBuffer)
  at void sun.security.ssl.HandshakeContext.dispatch(byte, sun.security.ssl.Plaintext)
  at void sun.security.ssl.TransportContext.dispatch(sun.security.ssl.Plaintext)
  at sun.security.ssl.Plaintext sun.security.ssl.SSLTransport.decode(sun.security.ssl.TransportContext, java.nio.ByteBuffer[], int, int, java.nio.ByteBuffer[], int, int)
  at sun.security.ssl.Plaintext sun.security.ssl.SSLEngineImpl.decode(java.nio.ByteBuffer[], int, int, java.nio.ByteBuffer[], int, int)
  at javax.net.ssl.SSLEngineResult sun.security.ssl.SSLEngineImpl.readRecord(java.nio.ByteBuffer[], int, int, java.nio.ByteBuffer[], int, int)
  at javax.net.ssl.SSLEngineResult sun.security.ssl.SSLEngineImpl.unwrap(java.nio.ByteBuffer[], int, int, java.nio.ByteBuffer[], int, int)
  at javax.net.ssl.SSLEngineResult sun.security.ssl.SSLEngineImpl.unwrap(java.nio.ByteBuffer, java.nio.ByteBuffer[], int, int)
  at javax.net.ssl.SSLEngineResult javax.net.ssl.SSLEngine.unwrap(java.nio.ByteBuffer, java.nio.ByteBuffer)
  at javax.net.ssl.SSLEngineResult org.apache.kafka.common.network.SslTransportLayer.handshakeUnwrap(boolean, boolean)
  at void org.apache.kafka.common.network.SslTransportLayer.doHandshake()
  at void org.apache.kafka.common.network.SslTransportLayer.handshake()
  at void org.apache.kafka.common.network.KafkaChannel.prepare()
  at void org.apache.kafka.common.network.Selector.pollSelectionKeys(java.util.Set, boolean, long)
  at void org.apache.kafka.common.network.Selector.poll(long)
  at void kafka.network.Processor.poll()
  at void kafka.network.Processor.run()
  at void java.lang.Thread.run()

-------------

PR Comment: https://git.openjdk.org/jdk17u-dev/pull/2750#issuecomment-2256582698


More information about the jdk-updates-dev mailing list