2017-11-01 9 views
0

우리는 우리의 Java 단일체에서 생산 문제를 가지고있었습니다. 사용자가 속도 저하 및 사이트를 사용할 수 없다고 불평했습니다. 쓰레드 덤프는 아래 스레드가 획득 한 잠금 장치에서 약 400 개의 쓰레드가 차단되었음을 나타냅니다.독서에서 차단 된 스레드 Zip 파일

차단 된 스레드는 모두 응용 프로그램 JAR 파일에서 VAADIN 리소스 파일을로드하려고 시도하는 블로킹 스레드 (+ - 1 마지막 프레임)와 거의 동일한 스택 추적을 갖습니다.

JAR에서 정적 파일을 읽을 때 스레드가 정지되었음을 의미합니까? 그리고 다른 사람들은 한 스레드가 그것을 읽는 것을 기다리고 있습니까?

아무도 모르게 왜 그런 일이 벌어졌으며 어떻게 방지 할 수 있습니까?

Java 버전 : 1.8.0_131

부두 버전 : 9.2.z-SNAPSHOT

"qtp489279267-42356" #42356 prio=5 os_prio=0 tid=0x00007fe7e4054800 nid=0x6f37 waiting for monitor entry [0x00007fe776831000] 
    java.lang.Thread.State: BLOCKED (on object monitor) 
    at java.util.zip.ZipFile$ZipEntryIterator.hasNext(ZipFile.java:492) 
    - waiting to lock <0x0000000700002e80> (a sun.net.www.protocol.jar.URLJarFile) 
    at java.util.zip.ZipFile$ZipEntryIterator.hasMoreElements(ZipFile.java:488) 
    at java.util.jar.JarFile$JarEntryIterator.hasNext(JarFile.java:253) 
    at java.util.jar.JarFile$JarEntryIterator.hasMoreElements(JarFile.java:262) 
    at org.eclipse.jetty.util.resource.JarFileResource.exists(JarFileResource.java:191) 
    at org.eclipse.jetty.webapp.WebAppContext.getResource(WebAppContext.java:372) 
    at org.eclipse.jetty.webapp.WebAppContext$Context.getResource(WebAppContext.java:1459) 
    at com.vaadin.terminal.gwt.server.AbstractApplicationServlet.serveStaticResourcesInVAADIN(AbstractApplicationServlet.java:1276) 
    at com.vaadin.terminal.gwt.server.AbstractApplicationServlet.serveStaticResources(AbstractApplicationServlet.java:1246) 
    at com.vaadin.terminal.gwt.server.AbstractApplicationServlet.service(AbstractApplicationServlet.java:423) 
    at example.ApplicationServlet.service(ApplicationServlet.java:37) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) 
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:808) 
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1669) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346) 
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262) 
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) 
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:186) 
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160) 
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346) 
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262) 
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346) 
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262) 
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) 
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585) 
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) 
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:577) 
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223) 
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127) 
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515) 
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185) 
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061) 
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) 
    at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:110) 
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) 
    at org.eclipse.jetty.server.Server.handle(Server.java:499) 
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:310) 
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257) 
    at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:540) 
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635) 
    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555) 
    at java.lang.Thread.run(Thread.java:748) 

답변

0

당신은 아마 그것을 짐작 오른쪽, 당신은 경쟁에 직면 할 것으로 보인다.

우리는 두 개의 관련된 관점에서 볼 수 있었다

:

  1. 잠금 경합
  2. 그것은 현재 사용 사례에 적용되지 않을 수도 있지만,뿐만 아니라 부하 생산 시스템에서 문제가 될 수
  3. : I/O 경합.

지금까지 스택 추적에서 확인한 증상은 잠금 경합이되는 것입니다.

개의 파일 (Java ZipFile 개체의 의미로)을 동시에 읽는 여러 명의 사용자가 공유하고있는 것으로 보입니다. 이로 인해 캐시 캐싱이 발생합니다. 유스 케이스에 따라 생각하는 것이 완전히 잘못된 것일 수 있습니다. 크기가 1 기가 바이트를 넘는 파일을 읽는 경우

그래서, 알고 유용 할 것이다

  1. 당신이 읽을 수있는 파일의 총 수;
  2. 이 파일의 중간 크기와 최대 크기.
  3. 이러한 파일의 평균 TTL, 즉 메모리에 한 번로드되는 데 필요한 시간.

주어진 기간 동안 적절한 양의 캐시 할 데이터가있는 경우 (예 : 몇 초 내에 1TB의 새로운 데이터를 가져와야하는 고객의 요구가 급증하지 않습니다.) 그리고 "상대적으로 작은"애드혹 소프트웨어 시스템을 관리한다면 간단한 해결책이 캐시 될 수 있습니다.

+0

글쎄, 모든 스택 추적은 어디서 Vaadin이 JAR의 VAADIN 폴더에서 리소스 (정적 파일)를로드하려고 시도 하는지를 보여줍니다. 내 정적 질문은 대체로 정적 파일이 클라이언트 (브라우저)에 의해 자주 읽혀지며 JAR 파일 읽기가 스레드를 오랫동안 멈출 수 있기 때문에 어떻게 될까요? (실제로 "존재"방법에) – redhead

+0

동기화가 Jar 파일 수준에서 수행 될 때 (즉, 올바르게 이해할 경우) 여러 프로세스가 병을 병렬로 읽을 수 없지만 각각 기다리는 중 왜 FS가 오버로드됩니까? 그렇지 않으면 차단 된 상태에 400 개의 스레드가 없습니다. 어쨌든 약 20 개의 정적 파일이 있습니다. – redhead