2017-11-01 12 views
0

私たちのJavaモノリスには生産上の問題がありました。ユーザーは、遅さやサイトが利用できないと不平を言った。スレッドダンプは、下のスレッドによって得られたロックで約400スレッドがブロックされていることを示しました。読み込み時にスレッドがブロックされました

これらのブロックされたスレッドはすべて、アプリケーション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. なお、本ユースケースには適用されないかもしれませんが、同様に負荷の下での生産システムに問題がある可能性があります:I/Oの競合。

これまでにスタックトレースから取得した症状は、ロック競合と思われるものです。

ファイル(Javaの意味ではZipFileオブジェクト)を複数の読者が同時に読んで共有しているようです。これにより、キャッシングのアイデアがもたらされますが、ユースケースに応じて考えることはまったく間違っているかもしれません。サイズが1ギガバイトを超えるファイルを読んでいる場合。

だから、あなたが読むことができるファイルの

  1. 総数を知ることは有用であろう。
  2. これらのファイルの中央値と最大サイズ。
  3. これらのファイルの平均TTL、つまり一度メモリにロードするのに必要な時間。

一定の期間にわたってキャッシュするデータ量が適切であれば(つまり、クライアントからの要求が急増しても、1 TBの新しいデータを数秒で取得する必要がありません)、「比較的小さな」アドホックソフトウェアシステムを管理する場合には、単純な解決法がキャッシュに入れることができます。

+0

まあ、すべてのスタックトレースは、VARADINがJARのVAADINフォルダからリソース(静的ファイル)をロードしようとしているところです。私の主な質問は、どのように起こるのでしょうか?通常、静的ファイルはクライアント(ブラウザ)によって頻繁に読み込まれ、JARファイルの読み込みはスレッドを長期間停止させる可能性があります。 – redhead

+0

Jarファイルレベルで同期が行われたとき(つまり、正しく理解していれば)、複数のプロセスがjarファイルを並列に読み取ることができないが、それぞれが待っているのはなぜですか?それ以外の場合は、ブロックされた状態で400スレッドはありません。とにかく約20の静的ファイルがあります。 – redhead