【问题标题】:Configuration and performance of the AsyncAppender in Logback frameworkLogback 框架中 AsyncAppender 的配置和性能
【发布时间】:2017-09-25 18:17:33
【问题描述】:

嗨,目前我正在研究 logback 日志框架。我遇到了 Async Appenders,它使用阻塞队列来记录消息,这样所有线程都将消息排入阻塞队列中,并且异步 appender 的工作线程负责将消息从队列记录到由 appender 决定的某个目的地,这可能是文件、数据库、套接字等

我可以看到响应时间的性能提升,因为主线程不会执行 I/O,它只会将消息推送到队列和后台工作线程中,以便异步追加器检索这些消息并将它们附加到日志文件中。

我的理解对吗? 我阅读了几个与异步追加器相关的配置属性,例如队列大小、maxFlushTime、neverBlock、discardingThreshold 和 includeCallerData。

我应该如何使用这些属性来提高日志记录的性能 我当前对 async Appender 的配置如下。

<appender name="ASYNC500" class="ch.qos.logback.classic.AsyncAppender">
   <appender-ref ref="fileAppender"/>
   <queueSize>500</queueSize>
  <maxFlushTime>1000</maxFlushTime>
</appender>

有人可以建议我进行一些调整以提高性能吗? ?普通 appender 和 Async Appender 哪个更好?

【问题讨论】:

    标签: java spring-boot logback


    【解决方案1】:

    先回答第二个问题……

    普通 appender 和 Async Appender 哪个更好?

    这里的答案是:视情况而定。在这里澄清一下使用AsyncAppender的利弊:

    • 优点:

      • 较低的日志事件延迟,即异步记录器完成任何给定 Logger.debug|info|warn|error 调用所需的时间将低于同步记录器。
      • 更高的吞吐量。这对于具有突发日志的应用程序特别有用,即偶尔的大量日志事件突发。异步日志记录 - 特别是如果配置的队列大小足够大以适应这些峰值 - 将防止在面对这些峰值时可能出现的日志调用缓慢。
    • 缺点:

      • 如果您的应用程序已经受 CPU 限制,那么启动另一个线程来处理异步日志事件不会带来太多好处
      • 如果您的应用程序发出日志事件的速度比异步追加器中的追加器处理它们的速度快,那么异步追加器将开始排队日志事件,如果这种情况继续下去,那么您的应用程序可能会面临缓慢发送和丢弃事件之间的决定
      • 在日志写回期间,从异步记录器传播错误比从同步记录器传播错误要复杂得多

    根据您的使用案例,您可能会发现其中一些优点和缺点比其他优点和缺点更重要。我建议在没有AsyncAppender 的情况下开始,并且仅在您有明显需要时才使用它。

    回到你的第一个问题...

    有人可以建议我进行一些调整以提高性能吗?

    这就是我先回答第二个问题的原因。在不知道您的应用程序的细节及其运行时配置(其主机上的内存和 CPU、AsyncAppender 包装的附加程序类型以及您对丢弃日志事件的容忍度)的情况下,不可能说出您应该如何配置它。但是,您将了解有关您自己的应用程序的所有这些信息,因此在考虑到这些知识后,我建议您在决定是否以及如何配置 AsyncAppender 时考虑以下事项:

    • queueSize:这个值越大,应用程序线程上的阻塞就越少。如果异步附加程序的队列已满,则应用程序线程将被阻止记录新事件,直到工作线程有机会从队列中删除项目。因此,如果应用程序倾向于产生足够的接近并发日志事件来填满队列,则增加 queueSize 将提高吞吐量。但请记住,只有在应用程序能够淹没现有队列大小并且以堆使用为代价时,这种吞吐量的提高才有意义。
    • includeCallerData:从日志事件中读取调用者提供的数据可能会很昂贵,您通常会发现将其设置为false 可以提高性能,除非您的日志事件中有一些定制的调用者提供的数据,否则您实际上不会丢失任何数据
    • neverBlock:将此设置为 true 将防止您的应用程序线程发生任何阻塞,但如果异步附加程序的内部缓冲区填满,则会以丢失日志事件为代价。

    所以...

    • 如果最大化吞吐量对您至关重要,并且您不关心丢失某些事件,请使用 neverBlock=true

    • 如果最大化吞吐量对您很重要,并且您的堆中有足够的空间,并且您无法容忍丢失日志事件,请使用:queueSize=_some_number_which exceeds_ the_maximum_queue_size_observed_in_testing_plus_25_percent_

    这里有更多详细信息:

    【讨论】:

    • is log4j2 与 logback 相同,来自 Log4j Performance Stats logging.apache.org/log4j/2.x/images/…
    • log4j2 是否比 logback 更好?
    • 我认为这些问题的答案很大程度上取决于您的使用模式。
    • 好的,目前我正在使用同步附加程序,如果需要,将切换到异步附加程序或异步记录器
    【解决方案2】:

    总之,如果您的旧应用仍在使用 Logback,并且不介意快速有损日志记录(带有缓冲刷新的异步日志记录),即在最坏的情况下,当缓冲的 ArrayBlockingQueue 已满或您正在记录时,请使用异步日志记录比您刷新到磁盘的速度更快,并且“可以丢失数据”,因为您可能记录的方式太多或应用程序响应时间更重要。

    否则,如果您想要一个无损附加程序,即设置 neverBlock=false(默认)和 discardingThreshold=0“未在上面讨论”-the logger starts discarding data <= INFO when queue size reaches a certain percentage by default,您将开始看到它的行为与 SyncAppender 相同。如果你真的记录了这么多,Log4j2 是一种方法,再次 YMMV!

    https://jira.qos.ch/browse/LOGBACK-1279

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-14
      相关资源
      最近更新 更多