tomcat nio模式下sendfile引起的NPE

这个bug困扰我们很长一段时间,最初是在生产环境发现的,为了确保项目发布,紧急情况下让应用切换成了BIO。后来没能重现,大家没足够重视,一直没有去跟这个问题,直到最近再次发现这个问题,发现是NIO模式默认对静态资源启用了sendfile以提升性能,但这里存在bug所致。官方已经在7051后续版本修复了这个问题,最好升级到最新版本。或者在server.xml的Connector节点里增加: useSendfile=”false” 来避免。

下面是相关的异常信息,如果你的tomcat是7051之前的版本,采用NIO并且没有显式的关闭sendfile,应用里有静态资源,访问静态资源时tomcat日志里出现了下面的异常(如果前边有nginx或apache返回502),很可能是同一问题:

 java.lang.NullPointerException
     at org.apache.catalina.connector.Request.notifyAttributeAssigned(Request.java:1565)
     at org.apache.catalina.connector.Request.setAttribute(Request.java:1556)
     at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:178)
     at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
     at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
     at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:410)
     at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1043)
     at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
     at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1721)
     at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1679)
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
     at java.lang.Thread.run(Thread.java:744)

java.lang.NullPointerException
     at org.apache.coyote.http11.InternalNioOutputBuffer.addToBB(InternalNioOutputBuffer.java:210)
     at org.apache.coyote.http11.InternalNioOutputBuffer.commit(InternalNioOutputBuffer.java:202)
     at org.apache.coyote.http11.AbstractHttp11Processor.action(AbstractHttp11Processor.java:781)
     at org.apache.coyote.Response.action(Response.java:172)
     at org.apache.coyote.http11.AbstractOutputBuffer.endRequest(AbstractOutputBuffer.java:302)
     at org.apache.coyote.http11.InternalNioOutputBuffer.endRequest(InternalNioOutputBuffer.java:120)
     at org.apache.coyote.http11.AbstractHttp11Processor.endRequest(AbstractHttp11Processor.java:1743)
     at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1087)
     at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
     at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1721)
     at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1679)
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
     at java.lang.Thread.run(Thread.java:744)

 java.lang.NullPointerException
     at org.apache.tomcat.util.buf.MessageBytes.toBytes(MessageBytes.java:244)
     at org.apache.catalina.connector.CoyoteAdapter.parsePathParameters(CoyoteAdapter.java:807)
     at org.apache.catalina.connector.CoyoteAdapter.postParseRequest(CoyoteAdapter.java:579)
     at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
     at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1043)
     at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
     at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1721)
     at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1679)
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
     at java.lang.Thread.run(Thread.java:744)

java.lang.NullPointerException
     at org.apache.coyote.http11.InternalNioOutputBuffer.flushBuffer(InternalNioOutputBuffer.java:233)
     at org.apache.coyote.http11.InternalNioOutputBuffer.endRequest(InternalNioOutputBuffer.java:121)
     at org.apache.coyote.http11.AbstractHttp11Processor.endRequest(AbstractHttp11Processor.java:1743)
     at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1087)
     at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
     at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1721)
     at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1679)
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
     at java.lang.Thread.run(Thread.java:744)         

发表评论

电子邮件地址不会被公开。 必填项已用*标注