2016-07-11 4 views
0

아파치 벤치 마크를 사용하여 1000 concurent 클라이언트와 200000 요청을 보낼 때 CME가 표시되지만이 값을 낮게 유지하면 fine.Below가 스택 추적입니다.log4j2 ParameterFormatter.appendCollection에서 ConcurrentModificationException이 발생했습니다.

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

어떤 Log4j 버전을 사용하고 있습니까? 최신 릴리스와 일치하지 않으므로 시도해 볼 수 있다면 도움이됩니다. 그것이 가치가있는 것을 위해, 나는 정말로 당신의 질문이 왜 떨어졌는지 확실하지 않습니다. – rgoers

+0

downvote가 이치에 맞지 않는다고 동의했습니다. 0으로 다시 올라갔습니다. :-) –

답변

1

을 사용하고 당신이 Log4j의 2 ParameterFormatter 텍스트 표현을 만들 수있는 요소 반복되는 동안 수정되는 컬렉션을 로그인하는 것으로 보인다.

stacktrace에서 Log4j 2가 동기식으로 로깅되도록 구성되어 있으므로 로깅중인 응용 프로그램 스레드와 다른 스레드가 Collection을 수정했을 수 있습니다.

동기 로깅에 대한 또 다른 사항은 벤치 마크 결과가 단순히 디스크 I/O 비용을 반영하거나 벤치 마크가 다중 스레드 인 경우 Log4j 2 appender의 잠금 경합 비용입니다. 이것은 아마도 지배적 인 비용 일 것입니다. 이것이 당신이 측정하고자하는 것이라면 위대한 것입니다. 그렇지 않으면 Log4j 2의 을 사용하는 것이 좋습니다. 비동기 로거를 사용하는 가장 간단한 방법은 단일 시스템 속성을 설정하는 것입니다 : Log4jContextSelectororg.apache.logging.log4j.core.async.AsyncLoggerContextSelector으로 설정하십시오.

+0

비동기 로거는 스냅 샷을 취하기 때문에 어떤 종류의 방어 복사본을 만드는 것과 같은 스냅 샷입니다. 그렇다면 gc를 더 많이 사용하여 트리거합니까? – Shashank

+0

비동기 로거는 매개 변수 개체의 방어 복사본을 사용할 수 없으므로 메시지가 백그라운드 스레드로 전달되기 전에 텍스트로 렌더링됩니다. 2.6 이후 Log4j는 가비지가 없게되지만 ArrayList.toString()을 호출하면 임시 객체가 생성됩니다. (동기 및 비동기 로깅 모두 동일합니다.) –

+0

GC 관점에서 비동기 로깅과 동기 로깅은 거의 같습니다. 차이점은 비동기 로거는 응용 프로그램 스레드에서 잠금 경합 및 I/O를 피할 수 있다는 것입니다. 그것이 성능 이점의 출처입니다. –

관련 문제