首页 > 解决方案 > 像 Log4j 这样的日志框架如何保证日志语句的顺序?

问题描述

这个问题一直困扰着我一段时间,像 Log4j 这样的流行日志框架如何允许并发、异步日志顺序保证日志顺序而没有性能瓶颈,即如果在日志语句L1之前调用日志语句L2L1那么如何保证在日志文件中之前L2

我知道 Log4j2 使用环形缓冲区和序列号,但它如何解决问题仍然不直观。

谁能给出一个直观的解释或指向我做同样的资源?

标签: javalogginglog4j2circular-buffer

解决方案


这一切都取决于您所说的“记录顺序”。在谈论单个线程时,会保留日志记录顺序,因为每个日志记录调用都会导致写入。

当异步记录每个日志事件时,它会按照接收顺序添加到队列中,并按照先进/先出顺序进行处理,无论它是如何到达那里的。这并不是很有挑战性,因为编写器是单线程的。

但是,如果您正在谈论跨线程的日志记录顺序,则永远无法保证 - 即使是同步记录 - 因为它不可能。线程 1 可以在线程 2 之前开始记录,但线程 2 可以在线程 1 之前的写入中到达同步点。同样,将事件添加到队列时也会发生同样的情况。在日志记录方法中锁定日志记录调用将保持顺序,但几乎没有任何好处,并且会带来灾难性的性能后果。

在多线程环境中,您完全有可能看到时间戳乱序的日志事件,因为线程 1 解析了时间戳,被线程 2 中断,然后线程 2 解析了时间戳并记录了事件。但是,如果您将日志写入 ElasticSearch 之类的东西,您将永远不会注意到,因为它按时间图对它们进行排序。


推荐阅读