【问题标题】:Log4J2 sync loggers faster than mixed async/sync loggersLog4J2 同步记录器比混合异步/同步记录器更快
【发布时间】:2015-05-19 23:50:07
【问题描述】:

基于https://logging.apache.org/log4j/2.x/manual/async.html,我想使用混合同步和异步记录器方法,以便从所有同步记录器的一些性能改进中受益。

基准代码:

public static void main(String[] args) {
    org.apache.logging.log4j.Logger log4j2Logger = org.apache.logging.log4j.LogManager
            .getLogger("com.foo.Bar");

    long start = System.currentTimeMillis();
    int nbLogMessages = 1 * 1000 * 1000;

    for (int i = 0; i < nbLogMessages; i++) {
        log4j2Logger.info("Log Message");
    }

    org.apache.logging.log4j.core.Logger coreLogger = (org.apache.logging.log4j.core.Logger) log4j2Logger;
    org.apache.logging.log4j.core.LoggerContext context = (org.apache.logging.log4j.core.LoggerContext) coreLogger
            .getContext();
    Map<String, org.apache.logging.log4j.core.Appender> appenders = context
            .getConfiguration().getAppenders();
    for (org.apache.logging.log4j.core.Appender appender : appenders
            .values()) {
        appender.stop();
    }

    long elapsed = System.currentTimeMillis() - start;
    System.out.println("Elapsed " + elapsed + "ms "
            + (nbLogMessages * 1000 / elapsed) + "logs/sec.");
}

Log4j2 配置正是文档中的配置 (https://logging.apache.org/log4j/2.x/manual/async.html):

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
  <Appenders>
    <RandomAccessFile name="RandomAccessFile" fileName="/tmp/asyncWithLocation.log" immediateFlush="false" append="false">
      <PatternLayout>
        <Pattern>%d %p %class{1.} [%t] %location %m %ex%n</Pattern>
      </PatternLayout>
    </RandomAccessFile>
  </Appenders>
  <Loggers>
    <!-- pattern layout actually uses location, so we need to include it -->
    <AsyncLogger name="com.foo.Bar" level="trace" includeLocation="true">
      <AppenderRef ref="RandomAccessFile"/>
    </AsyncLogger>
    <Root level="info" includeLocation="true">
      <AppenderRef ref="RandomAccessFile"/>
    </Root>
  </Loggers>
</Configuration>

使用混合的同步/异步记录器配置,我可以达到 33,400 个日志/秒。

现在,如果我将 AsyncLogger "com.foo.Bar" 替换为常规 Logger,我会得到大约 35,300 个日志/秒。

为什么同步记录器策略更快,根据图表它应该有更高的吞吐量?

在按照他们的建议进行基准测试之前,我尝试了各种其他方法,例如“预热”JVM,但没有帮助。

请注意,如果我将属性 Log4jContextSelector 设置为“org.apache.logging.log4j.core.async.AsyncLoggerContextSelector”以激活“所有异步”记录器,我会得到大约 86,400 个日志/秒。很遗憾,由于其他原因,我无法使用该选项。

使用 log4j2-2.3、disruptor-3.3.2。
操作系统是 Ubuntu,8 核。

【问题讨论】:

    标签: java logging asynchronous log4j2


    【解决方案1】:

    在开始测量之前,我建议您记录较少数量的消息,例如 100,000 条左右,然后在开始测量循环之前休眠一秒钟。 (您不想在这里测量 log4j 的初始化或 JVM 优化。)

    如果您在日志记录循环结束(尝试停止附加程序之前)之前进行测量,您的性能结果是什么?

    还可以尝试在您的配置中设置 includeLocation="false"。这应该有很大的不同。

    我认为您不应该手动停止附加程序(请参阅我对您其他问题的回答)。

    【讨论】:

    • 预热 + includeLocation="false" 的组合成功了,我得到 278K/sec 的混合异步和 209K/sec 的同步(和 249K/sec 的所有异步,这很奇怪) .
    • 测量很难。添加线程将强调差异。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-14
    • 1970-01-01
    相关资源
    最近更新 更多