Dear All, We are running Tomcat 8.5.23 production server on a CentOS 6.9 machine, Oracle JVM 1.8.0_144, and OpenSSL 1.1.0f. The server hosts a web application where almost all the traffic is https.
We used to have a Http11NioProtocol connector with Java SSL using HTTP 1.1 but we switched to Http2Protocol upgrade because of problems with Apple clients (KeepAlive timeout, server dropped the connection, etc..). We also switched to OpenSSL for ALPN. Since then we have had several problems with the different connectors, all of them tested with Tomcat 8.5.16, 8.5.20 and 8.5.23. - Http11NioProtocol has a memory leak, we experienced the same behaviour as this bug https://bz.apache.org/bugzilla/show_bug.cgi?id=57546 so we have to restart the server regularly. - Http11AprProtocol runs fine but the JVM crashes unexpectedly with a core dump from time to time. - Http11Nio2Protocol runs fine but some requests are not processed. We have not found a way to reproduce the problem but it happens once every 5 minutes. The server processes 1.13 million requests per day so it's one request failed every 4000 approximately. We can't reproduce the failed requests, but some crawling tools report them as if the server failed to respond (no status code) This is the exception we get: 05-Oct-2017 17:13:32.535 SEVERE [https-openssl-nio2-94.229.64.230-443-exec-19701] org.apache.coyote.AbstractProtocol$ConnectionHandler.process Error reading request, ignored java.lang.IllegalStateException at org.apache.coyote.http2.Http2UpgradeHandler.fill(Http2UpgradeHandler.java:1314) at org.apache.coyote.http2.Http2UpgradeHandler.fill(Http2UpgradeHandler.java:1290) at org.apache.coyote.http2.Http2Parser.readConnectionPreface(Http2Parser.java:574) at org.apache.coyote.http2.Http2UpgradeHandler.init(Http2UpgradeHandler.java:243) at org.apache.coyote.http2.Http2UpgradeHandler.upgradeDispatch(Http2UpgradeHandler.java:310) at org.apache.coyote.http11.upgrade.UpgradeProcessorInternal.dispatch(UpgradeProcessorInternal.java:54) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:53) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) at org.apache.tomcat.util.net.Nio2Endpoint$SocketProcessor.doRun(Nio2Endpoint.java:1693) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at org.apache.tomcat.util.net.AbstractEndpoint.processSocket(AbstractEndpoint.java:946) at org.apache.tomcat.util.net.SecureNio2Channel$HandshakeWriteCompletionHandler.completed(SecureNio2Channel.java:115) at org.apache.tomcat.util.net.SecureNio2Channel$HandshakeWriteCompletionHandler.completed(SecureNio2Channel.java:108) at sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:126) at sun.nio.ch.Invoker.invokeDirect(Invoker.java:157) at sun.nio.ch.UnixAsynchronousSocketChannelImpl.implWrite(UnixAsynchronousSocketChannelImpl.java:736) at sun.nio.ch.AsynchronousSocketChannelImpl.write(AsynchronousSocketChannelImpl.java:382) at sun.nio.ch.AsynchronousSocketChannelImpl.write(AsynchronousSocketChannelImpl.java:399) at java.nio.channels.AsynchronousSocketChannel.write(AsynchronousSocketChannel.java:577) at org.apache.tomcat.util.net.SecureNio2Channel.handshakeInternal(SecureNio2Channel.java:273) at org.apache.tomcat.util.net.SecureNio2Channel.handshake(SecureNio2Channel.java:204) at org.apache.tomcat.util.net.Nio2Endpoint$SocketProcessor.doRun(Nio2Endpoint.java:1671) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at org.apache.tomcat.util.net.AbstractEndpoint.processSocket(AbstractEndpoint.java:946) at org.apache.tomcat.util.net.SecureNio2Channel$HandshakeReadCompletionHandler.completed(SecureNio2Channel.java:98) at org.apache.tomcat.util.net.SecureNio2Channel$HandshakeReadCompletionHandler.completed(SecureNio2Channel.java:91) at sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:126) at sun.nio.ch.Invoker$2.run(Invoker.java:218) at sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:748) This is our current Connector configuration: <Connector port="443" address="xxx" protocol="org.apache.coyote.http11.Http11Nio2Protocol" SSLEnabled="true" maxThreads="1500" acceptCount="5000" scheme="https" secure="true" defaultSSLHostConfigName="xxx" hostName="xxx" connectionTimeout="70000" URIEncoding="UTF-8" server="Apache" enableLookups="false" compression="on" compressionMinSize="2048" compressableMimeType="text/html,text/xml,text/csv,text/css,text/javascript,text/html,text/plain,application/javascript,application/x-javascript" sslImplementationName="org.apache.tomcat.util.net.openssl.OpenSSLImplementation" ><UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" readTimeout="70000" writeTimeout="70000" maxConcurrentStreams="400" maxConcurrentStreamExecution="400"/> <SSLHostConfig hostName="xxx" disableSessionTickets="true" protocols= "TLSv1,TLSv1.1,TLSv1.2" ciphers="ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA" honorCipherOrder="true" > <Certificate certificateFile="xxx" certificateKeyFile="xxx" certificateChainFile="xxx"/> </SSLHostConfig> </Connector> We have experimented with different parameters of the Http2Protocol connector to improve performance and control the leak with Http11NioProtocol connector but the exceptions are there with any of the values or removing the extra parameters. We also tried Tomcat/9.0.0.M26 and the exception we got was: 22-Sep-2017 19:16:26.872 SEVERE [https-openssl-nio2-94.229.64.230-443-exec-229] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [default] in context with path [] threw exception java.lang.NullPointerException at org.apache.coyote.http2.HpackEncoder$TableEntry.access$100(HpackEncoder.java:339) at org.apache.coyote.http2.HpackEncoder.findInTable(HpackEncoder.java:297) at org.apache.coyote.http2.HpackEncoder.encode(HpackEncoder.java:150) at org.apache.coyote.http2.Http2UpgradeHandler.doWriteHeaders(Http2UpgradeHandler.java:573) at org.apache.coyote.http2.Http2AsyncUpgradeHandler.writeHeaders(Http2AsyncUpgradeHandler.java:138) at org.apache.coyote.http2.Stream.writeHeaders(Stream.java:411) at org.apache.coyote.http2.StreamProcessor.prepareResponse(StreamProcessor.java:100) ... Any suggestions? Thanks in advance. Eirik.