有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java 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在windows Server 2008上的Tomcat 7上运行的服务器。邮件1.4


共 (1) 个答案

  1. # 1 楼答案

    您可能想在Apache Log4j中检查关于记录器中线程阻塞的这个错误: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