【发布时间】:2018-01-02 07:11:08
【问题描述】:
当我在 logback 中查看 AsyncAppender 的文档时,我没有找到支持 AsyncAppender 的线程池设置之类的东西。
这是否意味着只有 1 个线程可以使用阻塞队列中的日志事件? (虽然日志事件可能由多个线程产生,比如 20-40)
谢谢
里昂
【问题讨论】:
标签: java logging logback slf4j
当我在 logback 中查看 AsyncAppender 的文档时,我没有找到支持 AsyncAppender 的线程池设置之类的东西。
这是否意味着只有 1 个线程可以使用阻塞队列中的日志事件? (虽然日志事件可能由多个线程产生,比如 20-40)
谢谢
里昂
【问题讨论】:
标签: java logging logback slf4j
来自the docs:
AsyncAppender 在 BlockingQueue 中缓冲事件。 AsyncAppender 创建的工作线程从队列头部获取事件,并将它们分派到附加到 AsyncAppender 的单个 appender。
然后查看代码; AsyncAppenderBase 启动 Thread 的单个实例以从 appender 的 blockingQueue 中获取事件。
所以,是的,只有一个工作线程,这个线程负责消费可能由多个应用程序线程发出的日志事件。
如果您担心此工作线程可能无法像生成事件一样快地处理这些事件,那么您可以调整以下属性:
queueSize:阻塞队列的最大容量。默认情况下,queueSize 设置为 256。discardingThreshold:默认情况下,当阻塞队列剩余20%容量时,会丢弃TRACE、DEBUG和INFO级别的事件,只保留WARN和ERROR级别的事件。要保留所有事件,请将 discardingThreshold 设置为 0。您可以增加queueSize 以确保您不会丢失任何事件(尽管会以资源使用为代价,因为保留的事件将位于应用程序的堆上,直到它们被分派到底层附加程序)。或者,您可以通过设置discardingThreshold 来提高性能 - 以丢失较低优先级事件为代价。
【讨论】:
我没有检查源代码,但我很确定是的,池中有一个线程。原因是多线程这个进程没有什么意义,因为任务的本质是单线程的。考虑您是否正在写入文件:不可能同时将两条消息附加到单个文件。
也许您希望字符串格式和 toString 方法在线程外调用...我希望它们不会,因为日志消息的参数可能会在调用后不久被修改。同步主要是为了防止 I/O 阻塞(例如磁盘延迟)影响性能关键代码。
【讨论】: