2012-10-04 4 views
4
내 제품의 성능 테스트를하는 동안 나는 지난 몇 일에서이 이상한 문제에 직면 한

, 난 자바 6을 사용하고, 성능 테스트 동안 3 프레임 워크와 바람둥이 7 서버자바 성능 문제는 - 톰캣 WebappClassLoader은

스트럿 고정 우리는 수천 개의 UI 요청을 서버 초기화 초기에 치기 시작합니다. 괜찮습니다. 그러나 몇 시간 후에 요청이 차단되어 점점 CPU 사용량이 100 %로 증가하고 심지어 UI도 액세스 할 수 없게됩니다. 스레드 덤프를 가져 왔을 때 아래의 문제를 분석해 보면 내가 일관되게 무엇을 얻고 있는지 알 수 있습니다.

""http-nio-8443"-exec-1305" daemon prio=10 tid=0x00007f0458538000 nid=0x56dd waiting for monitor entry [0x00007f04345c9000] 
    java.lang.Thread.State: BLOCKED (on object monitor) 
    at java.lang.Class.forName0(Native Method) 
    at java.lang.Class.forName(Class.java:247) 
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1663) 
    - locked <0x00000000a162f0c0> (a org.apache.catalina.loader.WebappClassLoader) 
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1521) 
    at java.beans.Introspector.instantiate(Introspector.java:1448) 
    at java.beans.Introspector.findExplicitBeanInfo(Introspector.java:431) 
    at java.beans.Introspector. (Introspector.java:380) 
    at java.beans.Introspector.getBeanInfo(Introspector.java:232) 
    at java.beans.Introspector.getBeanInfo(Introspector.java:218) 
    at com.googlecode.jsonplugin.JSONWriter.bean(JSONWriter.java:169) 
    at com.googlecode.jsonplugin.JSONWriter.process(JSONWriter.java:152) 
    at com.googlecode.jsonplugin.JSONWriter.value(JSONWriter.java:120) 
    at com.googlecode.jsonplugin.JSONWriter.write(JSONWriter.java:88) 
    at com.googlecode.jsonplugin.JSONUtil.serialize(JSONUtil.java:90) 
    at com.googlecode.jsonplugin.JSONResult.execute(JSONResult.java:119) 
    at com.opensymphony.xwork2.DefaultActionInvocation.executeResult(DefaultActionInvocation.java:348) 
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:253) 
    at com.facetime.imauditor.sreach.action.CustomRequestInterceptorJson.intercept(CustomRequestInterceptorJson.java:69) 
    at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224) 
    at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223) 
    at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455) 
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221) 
    at com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:221) 
    at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:86) 
    at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224) 
    at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223) 
    at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455) 
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221) 
    at com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:150) 
    at org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:48) 
    at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:86) 
    at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224) 
    at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223) 
    at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455) 
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221) 
    at com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:123) 
    at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224) 
    at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223) 
    at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455) 
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221) 
    at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:167) 
    at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:86) 
    at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224) 
    at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223) 
    at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455) 
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221) 
    at com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:105) 
    at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224) 
    at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223) 
    at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455) 
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221) 
    at org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:83) 
    at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224) 
    at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223) 
    at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455) 
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221) 
    at org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:207) 
    at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224) 
    at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223) 
    at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455) 
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221) 
    at com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:74) 
    at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224) 
    at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223) 
    at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455) 
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221) 
    at com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:127) 
    at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224) 
    at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223) 
    at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455) 
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221) 
    at org.apache.struts2.interceptor.ProfilingActivationInterceptor.intercept(ProfilingActivationInterceptor.java:107) 
    at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224) 
    at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223) 
    at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455) 
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221) 
    at org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:206) 
    at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224) 
    at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223) 
    at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455) 
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221) 
    at com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:115) 
    at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224) 
    at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223) 
    at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455) 
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221) 
    at com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:143) 
    at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224) 
    at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223) 
    at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455) 
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221) 
    at com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:121) 
    at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:86) 
    at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224) 
    at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223) 
    at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455) 
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221) 
    at org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:170) 
    at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224) 
    at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223) 
    at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455) 
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221) 
    at com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:123) 
    at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224) 
    at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223) 
    at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455) 
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221) 
    at com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:176) 
    at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224) 
    at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223) 
    at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455) 
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221) 
    at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:50) 
    at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:504) 
    at org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:419) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at com.facetime.imcoreserver.registration.AbsoluteSendRedirectFilter.doFilter(AbsoluteSendRedirectFilter.java:48) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164) 
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:403) 
    at org.apache.coyote.http11.Http11NioProcessor.process(Http11NioProcessor.java:369) 
    at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:317) 
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1532) 
    - locked <0x00000000abb53778> (a org.apache.tomcat.util.net.SecureNioChannel) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) 
    at java.lang.Thread.run(Thread.java:662) 

다음은 스레드 통계입니다.

Threads locking monitor=1 
Threads sleeping on monitor=0 
Threads waiting to lock monitor=1097 

이 점에 대한 도움은 정말 도움이 될 것입니다. 미리 감사드립니다.

+0

가비지 수집기 활동을 발생한 CPU 스파이크와 비교 했습니까? – wemu

+0

가비지 수집기가 잘 작동하는 것 같습니다. 위 덤프에서 – willsteel

+0

, "모니터 항목 [0x00007f04345c9000]"을 (를) 대기중인 것은 무엇입니까? 어쩌면 우리는 틀린 실을보고 있습니다. 메모리 사용량이 좋습니까? 아니면 사용자로드가 증가 할 때 메모리 사용량이 많이 증가합니까? – wemu

답변

1

UPDATE :

내가 최근에 비슷한 문제에 직면했다. 때로는 웹 응용 프로그램이 잘 프로그래밍되지 않은 경우 네트워크 소켓 (예 : 데이터베이스 연결 클래스)을 올바르게 정리하지 못할 수 있습니다. 호스트 (Tomcat JVM) 프로세스에서 너무 많은 오픈 파일 디스크립터로 이어진다. 그리고 그것은 당신이 직면하고있는 책임감을 이끌어 낼 수 있습니다.

그래서 제 경우에는 ThreadLocal generic을 사용하여 스레드별로 데이터베이스 연결을 설계하여 문제를 해결했습니다. 이것은 내 웹 애플리케이션 서비스 관리는 콩 :이 그 바람둥이 executor 스레드 당 하나의 TCP 소켓에 opend됩니다 보장합니다

private static ThreadLocal<YourConnectionClass> connection = new ThreadLocal<YourConnectionClass>(); 

public static YourConnectionClass getConnection(){ 
    if (connection.get() == null) connection.set(driver.getConnection()); 
    return connection.get(); 
} 

관리. 그 문제가 적용되면 내가 언급 한 것과 유사한 수정을 추가하면 문제가 사라질 것입니다. 잘, 그러나 그것의 단지 아직도 "추측". 귀하가 이에 해당하면 토우는 단순히 서버로 유닉스/리눅스 콘솔이를 입력하여 확인할 수 있습니다

netstat | grep <YOUR_TCP_PORT> 

또는 lsof를를 사용하여

(목록 열려있는 파일을). TCP 소켓은 열린 파일 핸들처럼 처리되기 때문입니다.
lsof <YOUR_JVM_PID> 

바람둥이 후 열기 소켓의 수를 시작하면

가 작거나 조금 다른 손에 당신의 책임 문제가 발생했을 때, 당신은 열려있는 소켓의 파일 기술자 누수가있을 수 있습니다 높은 파괴입니다.

두 번째 추측으로 자바 객체에서 HashTable을 올바르게 정리하지 않을 때 (자바 애플리케이션 코드에서 어딘가에) 자바에서도 발생할 수있는 HashTable 메모리 누수가있을 수 있습니다. 그러나 위의 설명에서 읽을 수 있듯이 아마도 그렇지 않을 수 있습니다.

환호 것이다


내 나이 답변 :

나는 그것의 가비지 컬렉션 전략을 내기.

올바른 JVM을 설정하여 다른 하나를 사용하여 시도하는 것으로 선택 :

-XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:SurvivorRatio=2 -XX:NewRatio=8 

확인이 링크 :

http://www.petefreitag.com/articles/gctuning/

http://www.idevelopment.info/data/Programming/java/miscellaneous_java/Java_Options_For_Garbage_Collection.html

+0

답장을 보내 주셔서 감사합니다, 위의 JVM 옵션도 시도했지만 여전히 운이 없습니다. – willsteel

+0

내 업데이트 된 게시물을 다시 확인하십시오 ... – willsteel

0

WebappClassLoader에서 동기화가 발생하여 비슷한 문제가 발견되었습니다. 많은 수의 제 3 자 라이브러리가 불행히도 loadClass 호출 수가 많을 때마다 나타납니다. 이상적인 해결책은 항상 loadClass를 호출하지 않는 것입니다. 그러나 이는 옵션이 아닐 수도 있습니다.

일부 사용자가 겪고 있던 교착 상태를 수정하기 위해 버그 48903/44041/48694의 일부로 Tomcat에 도입 된 변경 사항이 원인입니다. 제 생각에는

http://svn.apache.org/viewvc?view=revision&revision=927565

는 수정, 다행스럽게도 필자는 수정이 로컬 캐시 모니터를 입력하기 전에 확인하실 수 있습니다 것을 인정받을 수 동기화-ING에 지나치게 비관적이다; 이 일은 멀리 가야합니다.

0

Tomcat 8.0.16 이상으로 업그레이드하고 Loader 클래스를 org.apache.catalina.loader.ParallelWebappClassLoader로 설정하여 문제를 해결할 수 있습니다. [TOMCAT_HOME] /conf/context.xml, 다음 줄을 추가하고

<Loader loaderClass="org.apache.catalina.loader.ParallelWebappClassLoader" />

다시 시작에서

우리는 하이버 네이트와 스프링 JDBC는에 dB 결과 집합 행을 변환 할 것입니다 비슷한 문제가 있었다 목적. 이 잠금 동작은 많은 결과를 가진 많은 스레드를 실행하는 멍청이에게 심각한 영향을 미쳤습니다.

Tomcat7에서 Tomcat8의 Hibernate 및 Spring JDBC 응용 프로그램을 실행하는 사용자에게 ParallelWebappClassLoader를 사용하면 성능이 훨씬 향상 될 것을 권장합니다.