log4j错误邮件挂线程

时间:2015-01-27 09:23:29

标签: java multithreading email log4j

我们遇到了一些问题,我们的生产环境对请求的响应速度极慢,并发现Tomcat已经耗尽了工作线程。这部分是我们的错,因为一个老特征占用了线程,但我们也发现了一些关于log4j和邮件错误日志的有趣内容。有一个log4j错误日志记录线程试图发送阻止其他34个线程的邮件。阻塞线程中的线程转储如下所示:

"http-apr-80-exec-777" - Thread t@4195
   java.lang.Thread.State: RUNNABLE
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.read(SocketInputStream.java:150)
    at java.net.SocketInputStream.read(SocketInputStream.java:121)
    at com.sun.mail.util.TraceInputStream.read(TraceInputStream.java:97)
    at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
    at java.io.BufferedInputStream.read(BufferedInputStream.java:265)
    - locked <45b6408b> (a java.io.BufferedInputStream)
    at com.sun.mail.util.LineInputStream.readLine(LineInputStream.java:75)
    at com.sun.mail.smtp.SMTPTransport.readServerResponse(SMTPTransport.java:1440)
    at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1260)
    at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:370)
    at javax.mail.Service.connect(Service.java:275)
    at javax.mail.Service.connect(Service.java:156)
    at javax.mail.Service.connect(Service.java:105)
    at javax.mail.Transport.send0(Transport.java:168)
    at javax.mail.Transport.send(Transport.java:98)
    at org.apache.log4j.net.SMTPAppender.sendBuffer(SMTPAppender.java:416)
    at org.apache.log4j.net.SMTPAppender.append(SMTPAppender.java:256)
    at org.apache.log4j.AppenderSkeleton.doAppend(AppenderSkeleton.java:251)
    - locked <54ebd98f> (a org.apache.log4j.net.SMTPAppender)
    at org.apache.log4j.helpers.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:66)
    at org.apache.log4j.Category.callAppenders(Category.java:206)
    - locked <731a1e23> (a org.apache.log4j.spi.RootLogger)
    at org.apache.log4j.Category.forcedLog(Category.java:391)
    at org.apache.log4j.Category.error(Category.java:305)
    at org.apache.jsp.errorpage_jsp._jspService(errorpage_jsp.java:197)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:749)
    at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:489)
    at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:412)
    at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:339)
    at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:467)
    at org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:412)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:201)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:947)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1009)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:1852)
    - locked <6af9560> (a org.apache.tomcat.util.net.SocketWrapper)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

   Locked ownable synchronizers:
    - locked <7a82445e> (a java.util.concurrent.ThreadPoolExecutor$Worker)

虽然34个被阻止的线程看起来通常是这样的:

"http-apr-80-exec-787" - Thread t@4306
   java.lang.Thread.State: BLOCKED
    at org.apache.log4j.Category.callAppenders(Category.java:204)
    - waiting to lock <731a1e23> (a org.apache.log4j.spi.RootLogger) owned by "http-apr-80-exec-777" t@4195
    at org.apache.log4j.Category.forcedLog(Category.java:391)
    at org.apache.log4j.Category.error(Category.java:305)
    at org.apache.jsp.errorpage_jsp._jspService(errorpage_jsp.java:197)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:749)
    at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:489)
    at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:412)
    at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:339)
    at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:467)
    at org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:412)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:201)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:947)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1009)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:1852)
    - locked <2d079e0c> (a org.apache.tomcat.util.net.SocketWrapper)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

   Locked ownable synchronizers:
    - locked <7dac19bb> (a java.util.concurrent.ThreadPoolExecutor$Worker)

是什么导致这个?邮件服务器有问题吗? log4j中是否有任何可以防止或减少锁定后果的配置?

使用log4j 1.2.17,javax.mail 1.4在Windows Server 2008上的Tomcat 7上运行的服务器

1 个答案:

答案 0 :(得分:1)

您可能想要查看Apache Log4j中有关Logger中线程阻止的错误:https://issues.apache.org/bugzilla/show_bug.cgi?id=50213

在大多数情况下,这不应该是一个问题,但如果我们使用类似SMTPAppender的东西,这可能需要一些时间来执行,那么这可能会导致问题。

可能的解决方案是使用异步记录器

<appender name="asyncAppender" class="org.apache.log4j.AsyncAppender">
  <appender-ref ref="theTargetAppender"/>
  <param name="BufferSize" value="512" />
  <param name="Blocking" value="false" />
 </appender>

要记住的一件事是,如果您的程序在异步线程日志之前崩溃,那么它会异步,那么该日志消息可能会丢失。

更多信息: http://troyjsd.blogspot.sg/2009/07/user-complaints-of-slow-j2ee-pages.html