当前位置: 首页 > 知识库问答 >
问题:

Log4j2线程阻塞在OutputStreamManager.write

汪迪
2023-03-14

背景我使用log4j2(2.12.1)与同步根和异步记录器。Lmax环形缓冲区大小默认为256*1024。我在控制台的appender。我用JSON布局记录MapMessage。我的日志消息的平均大小约为100字节。

有了上面的细节,我注意到很少有线程被阻塞在

"http-nio-8080-exec-172" #451
   Thread State: BLOCKED (on object monitor) owned by "http-nio-8080-exec-148" Id=429
  at org.apache.logging.log4j.core.appender.OutputStreamManager.write(OutputStreamManager.java:231)
  - blocked on <0x000000003eb936ae> (a org.apache.logging.log4j.core.appender.OutputStreamManager)
  at org.apache.logging.log4j.core.appender.OutputStreamManager.writeBytes(OutputStreamManager.java:206)
  at org.apache.logging.log4j.core.layout.AbstractLayout.encode(AbstractLayout.java:211)
  at org.apache.logging.log4j.core.layout.AbstractLayout.encode(AbstractLayout.java:37)
  at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.directEncodeEvent(AbstractOutputStreamAppender.java:197)
  at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.tryAppend(AbstractOutputStreamAppender.java:190)
  at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.append(AbstractOutputStreamAppender.java:181)
  at org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:156)
  at org.apache.logging.log4j.core.config.AppenderControl.callAppender0(AppenderControl.java:129)
  at org.apache.logging.log4j.core.config.AppenderControl.callAppenderPreventRecursion(AppenderControl.java:120)
  at org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:84)
  at org.apache.logging.log4j.core.config.LoggerConfig.callAppenders(LoggerConfig.java:543)
  at org.apache.logging.log4j.core.config.LoggerConfig.processLogEvent(LoggerConfig.java:502)
  at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:485)
  at org.apache.logging.log4j.core.config.LoggerConfig.logParent(LoggerConfig.java:534)
  at org.apache.logging.log4j.core.config.LoggerConfig.processLogEvent(LoggerConfig.java:504)
  at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:485)
  at org.apache.logging.log4j.core.async.AsyncLoggerConfig.log(AsyncLoggerConfig.java:121)
  at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:460)
  at org.apache.logging.log4j.core.config.AwaitCompletionReliabilityStrategy.log(AwaitCompletionReliabilityStrategy.java:82)
  at org.apache.logging.log4j.core.Logger.log(Logger.java:162)
  at org.apache.logging.log4j.spi.AbstractLogger.tryLogMessage(AbstractLogger.java:2190)
  at org.apache.logging.log4j.spi.AbstractLogger.logMessageTrackRecursion(AbstractLogger.java:2144)
  at org.apache.logging.log4j.spi.AbstractLogger.logMessageSafely(AbstractLogger.java:2127)
  at org.apache.logging.log4j.spi.AbstractLogger.logIfEnabled(AbstractLogger.java:1828)
  at org.apache.logging.log4j.spi.AbstractLogger.info(AbstractLogger.java:1282)

我的问题是。。

  1. 环形缓冲区是否很快就满了,这导致主线程背压(在我的例子中,servlet容器线程是http-nio-8080-exec-148)?堆转储显示RingBuffer始终占用7MB(测试前后)

任何建议或想法都受到赞赏。

共有1个答案

邵胜涝
2023-03-14

该锁用于防止多个线程同时写入同一输出流,因为这可能导致数据混合。尽管不能保证,但许多OutputStream实现都会锁定写入调用,因此即使移除了锁,也会在OutputStream实现中阻塞。

这显然是因为正在使用的OutputStream正在从其他线程写入数据。此线程并不表示环形缓冲区已满,但可能其他线程因此被阻塞。我不清楚为什么你必须写控制台,但登录云提供了更多数据,说明你为什么不应该写,以及在云环境中运行时有哪些替代方案。

更新:在查看完整的线程转储后,我有一些观察结果:

  1. 有许多线程在com上等待。xxxx。阿皮。图书馆内部请求。执行(InternalRequest.java:273)。它们似乎在等待在另一个线程上执行的工作,但从线程转储中不清楚具体是什么

底线是,您正在同步地记录到OutputStream(可能是控制台),线程正在阻塞它,因为I/O速度很慢。

 类似资料:
  • 我有4-5个工作线程处理大型消息队列。我还有另一段代码,它使用2-3个worker运行。我想在处理大型消息队列时阻止所有其他工作者。 我正在使用JDK6和Jms 编辑: 队列进程工作者从未终止。当没有消息时,它们阻塞队列。这些工作者由执行器线程池管理,如果我使用读写锁,其中一个工作者也会被阻塞。此外,如果使用循环屏障,那么我必须终止线程,以便重新传递阻塞的第二个进程。由于工作者是由线程池管理的,所

  • 我编写了一个简单的类,我计划将其扩展为客户端套接字编程应用程序的一部分。类涉及一个BlockingQueue(我从这里复制了代码:相当于Java的BlockingQueue的C++)。当我创建了下面的包装类的一个实例后,我打算让它生成一个单独的线程,该线程只需执行BlockingQueue上阻塞的printer()函数,直到有一个或多个字符串可用,然后它只需将字符串打印到控制台窗口。在我的预期应用

  • 我正在尝试用Python编写一个程序。我想写的是一个脚本,它会立即向用户返回一条友好的消息,但会在后台生成一个长的子进程,它会处理几个不同的文件,并将它们写入一个祖父文件。我已经做了一些关于线程和处理的教程,但我遇到的是,无论我尝试什么,程序都会一直等待,直到子进程完成,然后才会向用户显示前面提到的友好消息。以下是我尝试过的: 线程示例: 我读过这些关于多线程的SO帖子如何在Python中使用线程

  • 摘要 本文描述了使用 QEMU 运行 RT-Thread 提供的基于多线程的非阻塞 socket 编程示例。 简介 随着物联网的发展,越来越多产品需要基于网络进行数据传输。在实际开发中,往往要求网络传输时不能阻塞当前线程,以致无法及时处理其他消息。在用户无法直接套用简单的 socket demo 时,RT-Thread 提供基于多线程的非阻塞 socket 编程示例,方便用户进行应用程序开发。 在

  • 本文向大家介绍Jquery ajax 同步阻塞引起的UI线程阻塞问题,包括了Jquery ajax 同步阻塞引起的UI线程阻塞问题的使用技巧和注意事项,需要的朋友参考一下 最近做一个项目,遇到了一个问题同步ajax引起的ui线程阻塞问题,下面把我的问题解决过程分享给大家。 事情起因是这样的,因为页面上有多个相似的异步请求动作,本着提高代码可重用性的原则,我封装了一个名为getData的函数,它接收

  • 我有一个vert。x标准Verticle基本上,它解析HttpRequest并准备JsonObject,然后我通过事件总线发送JsonObject。在另一个Worker verticale中,该事件被消耗,并将启动执行(包括对Penthao数据集成Java API的调用),它正在阻止API。完成“.kjb”文件的执行大约需要30分钟。但是vert。x不断警告Worker线程块,所以我的问题是ver