Logback框架中的AsyncAppender的配置和性能

时间:2017-09-25 18:17:33

标签: java spring-boot logback

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

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

我的理解是对的吗? 我读了几个与async appender相关的配置属性,如队列大小,maxFlushTime,neverBlock,discardingThreshold和includeCallerData。

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

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

有人可以建议我进行一些调整以获得性能。 ?哪个更好的普通appender或Async Appender?

2 个答案:

答案 0 :(得分:10)

首先回答第二个问题......

  

哪个更好的正常appender或Async Appender?

这里的答案是:取决于。为了澄清这里使用AsyncAppender

的利弊
  • 优点:

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

    • 如果您的应用程序已经受CPU限制,那么启动另一个线程来处理异步日志事件将不会带来太多好处
    • 如果您的应用程序比async appender内部的appender更快地发出日志事件,那么异步appender将开始排队日志事件,如果这种情况继续,那么您的应用程序可能会面临缓慢排放和丢弃事件之间的决定< / LI>
    • 在日志中从异步记录器写回发送程序时传播错误要比从同步记录器回写错误要复杂得多。

根据您的使用情况,您可能会发现其中一些优点和缺点比其他优点更重要。我建议在没有AsyncAppender的情况下开始,如果您有明确的需要,我建议只使用一个AsyncAppender

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

  

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

这就是我先回答第二个问题的原因。在不知道应用程序的具体情况及其运行时配置(主机上的内存和CPU,AsyncAppender包装的appender的类型以及丢弃日志事件的容忍度)的情况下,无法说出如何配置它。但是,您将了解有关您自己的应用程序的所有这些事情,因此,在考虑是否以及如何配置queueSize时,我建议考虑以下内容:

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

所以......

  • 如果最大化吞吐量对您而言至关重要且您不关心丢失某些事件,请使用queueSize=_some_number_which exceeds_ the_maximum_queue_size_observed_in_testing_plus_25_percent_

  • 如果最大化吞吐量对您很重要,并且您的堆中有足够的空间并且您无法容忍丢失日志事件,请使用:public void StartDialogue(Dialogue dialogue) { //Debug.Log("Start conversation with " + dialogue.name); cameradialogue.SetActive(true); FindObjectOfType<ThirdPersonCharacter> ().isStop = true; DialogueBox.SetActive (true); NameText.text = dialogue.name; sentences.Clear(); foreach (string sentence in dialogue.sentences) sentences.Enqueue (sentence); DisplayNextSentence(); }

此处有更多详情:

答案 1 :(得分:0)

总而言之,如果您的旧版应用程序仍在使用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