Details
-
Type: Bug
-
Status: Closed
-
Priority: Major
-
Resolution: Fixed
-
Affects Version/s: 1.6DR#3
-
Component/s: Framework
-
Labels:None
-
Environment:multiprocessor server, jdk 1.5
-
Workaround Exists:Yes
-
Workaround Description:turn off accept gzip in the browser; however, this is not likely an acceptable workaround for most users
Description
CSS resources can be served stressfully with the following script:
while true; do for x in 1 2 3 4 5 6 7 8 9 0; do curl -H "Accept-Encoding: gzip,deflate" -O http://vorlon.ice:8080/component-showcase/xmlhttp/css/xp/css-images/over-right-mid.gif -O http://vorlon.ice:8080/component-showcase/xmlhttp/css/xp/xp.css& done; sleep 1; done
When this is run against a multiprocessor machine (both mac and linux have been tested),
after a short period the CPU utilization will go to 100% and will not subside until the server is killed. A typical thread in this state is the following:
[1] java.util.zip.Deflater.deflateBytes (native method)
[2] java.util.zip.Deflater.deflate (Deflater.java:284)
[3] java.util.zip.DeflaterOutputStream.deflate (DeflaterOutputStream.java:154)
[4] java.util.zip.DeflaterOutputStream.write (DeflaterOutputStream.java:114)
[5] java.util.zip.GZIPOutputStream.write (GZIPOutputStream.java:72)
[6] com.icesoft.faces.webapp.http.common.standard.CompressingServer.copy (CompressingServer.java:72)
[7] com.icesoft.faces.webapp.http.common.standard.CompressingServer.access$200 (CompressingServer.java:15)
[8] com.icesoft.faces.webapp.http.common.standard.CompressingServer$CompressingResponse.writeBodyFrom (CompressingServer.java:65)
[9] com.icesoft.faces.webapp.http.core.ServeCSSResource$1.respond (ServeCSSResource.java:32)
[10] com.icesoft.faces.webapp.http.common.standard.CacheControlledServer$EnhancedRequest$1.respond (CacheControlledServer.java:70)
[11] com.icesoft.faces.webapp.http.common.standard.CompressingServer$CompressingRequest$1.respond (CompressingServer.java:44)
[12] com.icesoft.faces.webapp.http.servlet.ServletRequestResponse.respondWith (ServletRequestResponse.java:121)
[13] com.icesoft.faces.webapp.http.common.standard.CompressingServer$CompressingRequest.respondWith (CompressingServer.java:42)
[14] com.icesoft.faces.webapp.http.common.standard.CacheControlledServer$EnhancedRequest.respondWith (CacheControlledServer.java:63)
[15] com.icesoft.faces.webapp.http.core.ServeCSSResource.service (ServeCSSResource.java:29)
[16] com.icesoft.faces.webapp.http.common.standard.CacheControlledServer.service (CacheControlledServer.java:42)
[17] com.icesoft.faces.webapp.http.common.standard.PathDispatcherServer$Matcher.serviceOnMatch (PathDispatcherServer.java:50)
[18] com.icesoft.faces.webapp.http.common.standard.PathDispatcherServer.service (PathDispatcherServer.java:19)
[19] com.icesoft.faces.webapp.http.common.standard.CompressingServer.service (CompressingServer.java:26)
[20] com.icesoft.faces.webapp.http.core.ResourceServer.service (ResourceServer.java:30)
[21] com.icesoft.faces.webapp.http.servlet.BasicAdaptingServlet.service (BasicAdaptingServlet.java:16)
[22] com.icesoft.faces.webapp.http.servlet.PathDispatcher$Matcher.serviceOnMatch (PathDispatcher.java:41)
[23] com.icesoft.faces.webapp.http.servlet.PathDispatcher.service (PathDispatcher.java:18)
[24] com.icesoft.faces.webapp.http.servlet.MainServlet.service (MainServlet.java:47)
[25] javax.servlet.http.HttpServlet.service (HttpServlet.java:802)
[26] org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:237)
[27] org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:157)
[28] org.apache.catalina.core.StandardWrapperValve.invoke (StandardWrapperValve.java:214)
[29] org.apache.catalina.core.StandardValveContext.invokeNext (StandardValveContext.java:104)
[30] org.apache.catalina.core.StandardPipeline.invoke (StandardPipeline.java:520)
[31] org.apache.catalina.core.StandardContextValve.invokeInternal (StandardContextValve.java:198)
[32] org.apache.catalina.core.StandardContextValve.invoke (StandardContextValve.java:152)
[33] org.apache.catalina.core.StandardValveContext.invokeNext (StandardValveContext.java:104)
[34] org.apache.catalina.core.StandardPipeline.invoke (StandardPipeline.java:520)
[35] org.apache.catalina.core.StandardHostValve.invoke (StandardHostValve.java:137)
[36] org.apache.catalina.core.StandardValveContext.invokeNext (StandardValveContext.java:104)
[37] org.apache.catalina.valves.ErrorReportValve.invoke (ErrorReportValve.java:118)
[38] org.apache.catalina.core.StandardValveContext.invokeNext (StandardValveContext.java:102)
[39] org.apache.catalina.core.StandardPipeline.invoke (StandardPipeline.java:520)
[40] org.apache.catalina.core.StandardEngineValve.invoke (StandardEngineValve.java:109)
[41] org.apache.catalina.core.StandardValveContext.invokeNext (StandardValveContext.java:104)
[42] org.apache.catalina.core.StandardPipeline.invoke (StandardPipeline.java:520)
[43] org.apache.catalina.core.ContainerBase.invoke (ContainerBase.java:929)
[44] org.apache.coyote.tomcat5.CoyoteAdapter.service (CoyoteAdapter.java:160)
[45] org.apache.coyote.http11.Http11Processor.process (Http11Processor.java:799)
[46] org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection (Http11Protocol.java:705)
[47] org.apache.tomcat.util.net.TcpWorkerThread.runIt (PoolTcpEndpoint.java:577)
[48] org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run (ThreadPool.java:683)
[49] java.lang.Thread.run (Thread.java:613)
By instrumenting the CompressingServer, it has been verified that the CPU activity is occurring only in the java.util.zip package. This is likely a zip implementation bug (lack of thread safety, perhaps in a native library) so the fix may be either to disable gzip encoding or to apply our own locking to ensure single threaded access to the gzip library.
Rather than compress static resources each time they are served, it may be preferable to pre-compress the resources, storing the compressed versions on the filesystem, and simply serve the compressed versions.