当我使用apache基准测试来向1000 concurent客户端发送200000请求时,我正在获取CME,但如果保持这些值较低,则可以正常工作。下面是堆栈跟踪:
2016-07-11 21:02:26,829 http-bio-8080-exec-284 ERROR An exception occurred processing Appender debug-log java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
at org.apache.logging.log4j.message.ParameterFormatter.appendCollection(ParameterFormatter.java:575)
at org.apache.logging.log4j.message.ParameterFormatter.appendPotentiallyRecursiveValue(ParameterFormatter.java:483)
at org.apache.logging.log4j.message.ParameterFormatter.recursiveDeepToString(ParameterFormatter.java:429)
at org.apache.logging.log4j.message.ParameterFormatter.formatMessage2(ParameterFormatter.java:189)
at org.apache.logging.log4j.message.ParameterizedMessage.formatTo(ParameterizedMessage.java:217)
at org.apache.logging.log4j.core.pattern.MessagePatternConverter.format(MessagePatternConverter.java:65)
at org.apache.logging.log4j.core.pattern.PatternFormatter.format(PatternFormatter.java:38)
at org.apache.logging.log4j.core.layout.PatternLayout$PatternSerializer.toSerializable(PatternLayout.java:288)
at org.apache.logging.log4j.core.layout.PatternLayout.toText(PatternLayout.java:194)
at org.apache.logging.log4j.core.layout.PatternLayout.encode(PatternLayout.java:180)
at org.apache.logging.log4j.core.layout.PatternLayout.encode(PatternLayout.java:57)
at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.directEncodeEvent(AbstractOutputStreamAppender.java:120)
at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.tryAppend(AbstractOutputStreamAppender.java:113)
at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.append(AbstractOutputStreamAppender.java:104)
at org.apache.logging.log4j.core.appender.RollingFileAppender.append(RollingFileAppender.java:86)
at org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:155)
at org.apache.logging.log4j.core.config.AppenderControl.callAppender0(AppenderControl.java:128)
at org.apache.logging.log4j.core.config.AppenderControl.callAppenderPreventRecursion(AppenderControl.java:119)
at org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:84)
at org.apache.logging.log4j.core.config.LoggerConfig.callAppenders(LoggerConfig.java:390)
at org.apache.logging.log4j.core.config.LoggerConfig.processLogEvent(LoggerConfig.java:375)
at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:359)
at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:349)
at org.apache.logging.log4j.core.config.AwaitCompletionReliabilityStrategy.log(AwaitCompletionReliabilityStrategy.java:63)
at org.apache.logging.log4j.core.Logger.logMessage(Logger.java:146)
at org.apache.logging.log4j.spi.AbstractLogger.logMessage(AbstractLogger.java:2025)
at org.apache.logging.log4j.spi.AbstractLogger.logIfEnabled(AbstractLogger.java:1898)
at org.apache.logging.slf4j.Log4jLogger.debug(Log4jLogger.java:129)
编辑:我正在使用log4j2 2.6
答案 0 :(得分:1)
在Log4j 2 ParameterFormatter
迭代其元素以创建文本表示时,您似乎正在记录正在修改的Collection。
从堆栈跟踪中,Log4j 2被配置为同步日志,因此可能由另一个线程修改Collection而不是正在记录的应用程序线程。
同步日志记录的另一个问题是,您的基准测试结果可能只是反映了磁盘I / O的成本,或者,如果您的基准测试是多线程的,那么Log4j 2 appender中的锁争用成本。这可能是主要成本。如果这是你想要测量的那么好。否则,我强烈建议您使用Log4j 2' Async Loggers。使用异步记录器的最简单方法是设置单个系统属性:将Log4jContextSelector
设置为org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
。