SSL reverse proxy to CXF endpoint on JBoss Fuse 6.1 causes high cpu

Solution Verified - Updated -

Environment

JBoss Fuse 6.1
Apache HTTPD 2.x

Issue

When a long running request to a CXF Web Service running on Fuse takes longer than the mod_ssl SSLCacheTimeout we get high CPU on the Fuse Java process.

Steps to reproduce:
1) Start with a fresh install of JBoss Fuse 6.1
2) Unzip jetty-issue-demo.zip
3) Set the JKS path in jetty-issue-demo.xml (JKS file provided in zip)
4) build jetty-issue-demo with the following command:

mvn clean install

5) cd $FUSE_HOME
6) uncomment admin user in etc/user.properties
7) install feature camel-jackson
8) install feature camel-mvel
9) install wrap:mvn:org.jasypt/jasypt-spring31/1.9.0
10) install jetty-issue-demo
11) verify the CXF endpoint is deployed by running:

cxf:list-endpoints

12) Install Apache HTTPD (tested with version 2.4.10)
13) Install Apache mod_ssl module
14) Generate a key using the instructions provided here
15) Copy the following configuration to a new file in conf.d:

LoadModule ssl_module modules/mod_ssl.so
Listen 8443
AddType application/x-x509-ca-cert .crt
AddType application/x-pkcs7-crl    .crl
SSLPassPhraseDialog  builtin
SSLSessionCache         shmcb:/var/cache/mod_ssl/scache(512000)
SSLSessionCacheTimeout  300


#----------------------------------
# 443
#----------------------------------
NameVirtualHost *:8443
<VirtualHost *:8443>
        ServerName sslproxy.usersys.redhat.com
        ServerAlias sslproxy.usersys.redhat.com
        SSLEngine on
        SSLCertificateFile      /etc/pki/tls/certs/sslproxy.usersys.redhat.com.crt
        SSLCertificateKeyFile   /etc/pki/tls/private/sslproxy.usersys.redhat.com.key

        ErrorLog logs/8443_error_log
        # Host Time "Request String" Bytes Status ServerActioningRequest ThisServerName TimeTakenMicroseconds(/1000000)
        CustomLog logs/8443_balancer_log  "%h %t \"%r\" %b %s %{BALANCER_WORKER_NAME}e %v %D"
        LogLevel warn
        SSLProxyEngine On

        # CXF REST endpoint
        <Proxy balancer://cxfrs>
           BalancerMember https://localhost:9292/demo retry=10
        </Proxy>
        ProxyPass /demo balancer://cxfrs

</VirtualHost>

16) Start Apache HTTPD, and verify you can get high cpu by accessing the application on the following url:

https://localhost:8443/demo/aaa

Resolution

There is a bug long running request to a CXF Web Service may lead to high CPU opened.
It is fixed in Fuse 6.1 R2P4.

Diagnostic Steps

When checking the OS High CPU thread against the corresponding Java thread, the threads causing high CPU look like this:

"qtp680330057-225" prio=10 tid=0x00007f42dc732000 nid=0x33f3 runnable [0x00007f42a8e40000]
   java.lang.Thread.State: RUNNABLE
        at org.eclipse.jetty.http.HttpGenerator.flushBuffer(HttpGenerator.java:811)
        at org.eclipse.jetty.http.AbstractGenerator.flush(AbstractGenerator.java:443)
        at org.eclipse.jetty.server.HttpOutput.flush(HttpOutput.java:100)
        at org.eclipse.jetty.server.AbstractHttpConnection$Output.flush(AbstractHttpConnection.java:1123)
        at org.eclipse.jetty.server.AbstractHttpConnection$Output.sendContent(AbstractHttpConnection.java:1237)
        at org.apache.cxf.transport.http_jetty.JettyHTTPDestination$JettyOutputStream.copyFrom(JettyHTTPDestination.java:414)
        at org.apache.cxf.helpers.IOUtils.copy(IOUtils.java:105)
        at org.apache.cxf.transport.http.AbstractHTTPDestination$WrappedOutputStream.copyFrom(AbstractHTTPDestination.java:706)
        at org.apache.cxf.helpers.IOUtils.copy(IOUtils.java:105)
        at org.apache.cxf.helpers.IOUtils.copyAndCloseInput(IOUtils.java:113)
        at org.apache.cxf.jaxrs.provider.BinaryDataProvider.copyInputToOutput(BinaryDataProvider.java:136)
        at org.apache.cxf.jaxrs.provider.BinaryDataProvider.writeTo(BinaryDataProvider.java:105)
        at org.apache.cxf.jaxrs.utils.JAXRSUtils.writeMessageBody(JAXRSUtils.java:1317)
        at org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.serializeMessage(JAXRSOutInterceptor.java:284)
        at org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.processResponse(JAXRSOutInterceptor.java:157)
        at org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.handleMessage(JAXRSOutInterceptor.java:86)
        at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
        - locked <0x00000000e2783df8> (a org.apache.cxf.phase.PhaseInterceptorChain)
        at org.apache.cxf.interceptor.OutgoingChainInterceptor.handleMessage(OutgoingChainInterceptor.java:81)
        at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
        - locked <0x00000000e27424c0> (a org.apache.cxf.phase.PhaseInterceptorChain)
        at org.apache.cxf.phase.PhaseInterceptorChain.resume(PhaseInterceptorChain.java:242)
        - locked <0x00000000e27424c0> (a org.apache.cxf.phase.PhaseInterceptorChain)
        at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:78)
        - locked <0x00000000e27424c0> (a org.apache.cxf.phase.PhaseInterceptorChain)
        at org.apache.cxf.transport.http_jetty.JettyHTTPDestination.serviceRequest(JettyHTTPDestination.java:355)
        at org.apache.cxf.transport.http_jetty.JettyHTTPDestination.doService(JettyHTTPDestination.java:319)
        at org.apache.cxf.transport.http_jetty.JettyHTTPHandler.handle(JettyHTTPHandler.java:72)
        at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1088)
        at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1024)
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
        at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:193)
        at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)
        at org.eclipse.jetty.server.Server.handleAsync(Server.java:410)
        at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:519)
        at org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:971)
        at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:1033)
        at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:644)
        at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:235)
        at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)
        at org.eclipse.jetty.io.nio.SslConnection.handle(SslConnection.java:196)
        at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:667)
        at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:52)
        at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)
        at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)
        at java.lang.Thread.run(Thread.java:744)
"qtp680330057-223" prio=10 tid=0x00007f42dc72d800 nid=0x33f1 runnable [0x00007f42a9041000]
   java.lang.Thread.State: RUNNABLE
        at sun.security.ssl.SSLEngineImpl.getHandshakeStatus(SSLEngineImpl.java:548)
        at org.eclipse.jetty.io.nio.SslConnection.process(SslConnection.java:351)
        - locked <0x00000000e317d4b0> (a org.eclipse.jetty.io.nio.SslConnection)
        at org.eclipse.jetty.io.nio.SslConnection.access$900(SslConnection.java:48)
        at org.eclipse.jetty.io.nio.SslConnection$SslEndPoint.flush(SslConnection.java:690)
        at org.eclipse.jetty.io.nio.SslConnection$SslEndPoint.flush(SslConnection.java:697)
        at org.eclipse.jetty.http.HttpGenerator.flushBuffer(HttpGenerator.java:838)
        at org.eclipse.jetty.http.AbstractGenerator.flush(AbstractGenerator.java:443)
        at org.eclipse.jetty.server.HttpOutput.flush(HttpOutput.java:100)
        at org.eclipse.jetty.server.AbstractHttpConnection$Output.flush(AbstractHttpConnection.java:1123)
        at org.eclipse.jetty.server.AbstractHttpConnection$Output.sendContent(AbstractHttpConnection.java:1237)
        at org.apache.cxf.transport.http_jetty.JettyHTTPDestination$JettyOutputStream.copyFrom(JettyHTTPDestination.java:414)
        at org.apache.cxf.helpers.IOUtils.copy(IOUtils.java:105)
        at org.apache.cxf.transport.http.AbstractHTTPDestination$WrappedOutputStream.copyFrom(AbstractHTTPDestination.java:706)
        at org.apache.cxf.helpers.IOUtils.copy(IOUtils.java:105)
        at org.apache.cxf.helpers.IOUtils.copyAndCloseInput(IOUtils.java:113)
        at org.apache.cxf.jaxrs.provider.BinaryDataProvider.copyInputToOutput(BinaryDataProvider.java:136)
        at org.apache.cxf.jaxrs.provider.BinaryDataProvider.writeTo(BinaryDataProvider.java:105)
        at org.apache.cxf.jaxrs.utils.JAXRSUtils.writeMessageBody(JAXRSUtils.java:1317)
        at org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.serializeMessage(JAXRSOutInterceptor.java:284)
        at org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.processResponse(JAXRSOutInterceptor.java:157)
        at org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.handleMessage(JAXRSOutInterceptor.java:86)
        at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
        - locked <0x00000000e354cda8> (a org.apache.cxf.phase.PhaseInterceptorChain)
        at org.apache.cxf.interceptor.OutgoingChainInterceptor.handleMessage(OutgoingChainInterceptor.java:81)
        at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
        - locked <0x00000000e31921c8> (a org.apache.cxf.phase.PhaseInterceptorChain)
        at org.apache.cxf.phase.PhaseInterceptorChain.resume(PhaseInterceptorChain.java:242)
        - locked <0x00000000e31921c8> (a org.apache.cxf.phase.PhaseInterceptorChain)
        at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:78)
        - locked <0x00000000e31921c8> (a org.apache.cxf.phase.PhaseInterceptorChain)
        at org.apache.cxf.transport.http_jetty.JettyHTTPDestination.serviceRequest(JettyHTTPDestination.java:355)
        at org.apache.cxf.transport.http_jetty.JettyHTTPDestination.doService(JettyHTTPDestination.java:319)
        at org.apache.cxf.transport.http_jetty.JettyHTTPHandler.handle(JettyHTTPHandler.java:72)
        at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1088)
        at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1024)
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
        at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:193)
        at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)
        at org.eclipse.jetty.server.Server.handleAsync(Server.java:410)
        at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:519)
        at org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:971)
        at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:1033)
        at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:644)
        at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:235)
        at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)
        at org.eclipse.jetty.io.nio.SslConnection.handle(SslConnection.java:196)
        at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:667)
        at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:52)
        at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)
        at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)
        at java.lang.Thread.run(Thread.java:744)

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.

Close

Welcome! Check out the Getting Started with Red Hat page for quick tours and guides for common tasks.