我正在编写一个JMH基准来测试logback的AsyncAppender的性能。
作为一个起点,我查看了log4j2的性能测试,但看起来它们不是端到端测量。例如,此处的测试Log4j2 Async Appender Benchmark仅测试将可记录数据包装在对象中并将其导入到破坏程序(后备队列)中的吞吐量。
@Benchmark
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
public void throughput2Params() {
logger.info("p1={}, p2={}", one, two);
}
这是全部还是我错过了一个测试,其中整个测量是从调用logger.info()到后台线程将数据写入磁盘/控制台/ db等?
由于
答案 0 :(得分:2)
使用JMH对端到端异步日志记录进行基准测试(使用像FileAppender这样的真正的appender)的问题是JMH非常快地生成许多日志事件。 FileAppender无法跟上,因此(固定大小)异步队列立即填满。
队列填满后,日志记录性能会降低到比普通同步文件日志记录更差的程度。
我们发现我们需要非常清楚我们想要测量的内容,最后我们分别测量了事件在空间中排队的速度,以及FileAppender将事件写入磁盘的速度。
使用JMH很难在端到端测试中同时测量两者,因为JMH不会让你控制你发射的事件数量(据我所知)。因此很难避免填满队列。我怀疑你对队列已满后异步日志记录的速度不感兴趣,因为这种情况非常罕见。
我们为Log4j2 performance tests采用的方法是将JMH与no-op appender一起用于异步日志记录测试,并为同步文件日志记录提供单独的JMH基准测试。
对于原始Async Logger performance tests,我们编写了一个自定义性能测试框架,该框架在不超过队列大小的突发事件中进行了测试。 (PerfTest,MTPerfTest和PerfTestDriver类可以在Log4j 2单元测试源目录中找到。)这也不容易:你需要确保测试正确预热,确保所有日志记录线程都从同时,在测试驱动程序的单独JVM中运行基准测试并以某种方式收集结果等。
P.S。
请注意,ConsoleAppender比记录到文件大约慢50倍(!)。使用控制台日志记录来比较日志库的性能不是一个好主意。