webentwicklung-frage-antwort-db.com.de

Anlegestelle 9 hängt, QueuedThreadPool wird größer

Wir haben kürzlich unsere Jetty-Server von Version 6.1.25 auf 9.0.4 aktualisiert. Sie werden auf Java 1.7.0_11 64-Bit auf einem Windows 2008-Server bereitgestellt.

Abgesehen von den erforderlichen Konfigurationsänderungen für Jetty (start.ini - very Nice) haben wir alle JVM-Flags auf dem vorherigen Stand gehalten. 6 Tage nach der Bereitstellung in der Produktionsumgebung reagierte der Server nicht mehr auf HTTP-Anforderungen. Die interne "Heartbeat" -Verarbeitung lief während dieser Zeit normal weiter, es wurden jedoch keine externen Anforderungen verarbeitet. Der Dienst wurde neu gestartet und 6 Tage später reagierte er erneut nicht mehr.

Bei meiner ersten Überprüfung dachte ich, ich hätte etwas mit https://bugs.Eclipse.org/bugs/show_bug.cgi?id=357318 zu tun. Dieses JVM-Problem wurde jedoch von Java 1.8_0XX auf Java 1.7.0_06 zurückportiert. Dies veranlasste mich, die Thread-Verarbeitung zu überprüfen.

Dachte, es könnte mit dem Fall 400617/410550 auf der Eclipse-Site zusammenhängen, obwohl er sich nicht so darstellt wie der Bericht, und der Fall war anscheinend in Jetty 9.0.3 gelöst worden.

Die Überwachung der Anwendung über JMX zeigt, dass die Anzahl der Threads für "qtp" -Threads im Laufe der Zeit weiter zunimmt und ich bei der Suche nach einer Lösung erfolglos geblieben bin. Die Thread-Konfiguration ist derzeit festgelegt für:

threads.min=10
threads.max=200
threads.timeout=60000

Alle qtp-Threads befinden sich normalerweise im Status WAITING mit dem folgenden Stack-Trace:

Name: qtp1805176801-285
State: WAITING on [email protected]
Total blocked: 0  Total waited: 110

Stack trace: 
Sun.misc.Unsafe.park(Native Method)
Java.util.concurrent.locks.LockSupport.park(Unknown Source)
Java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(Unknown Source)
Java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(Unknown Source)
Java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(Unknown Source)
Java.util.concurrent.Semaphore.acquire(Unknown Source)
org.Eclipse.jetty.util.BlockingCallback.block(BlockingCallback.Java:96)
org.Eclipse.jetty.server.HttpConnection$Input.blockForContent(HttpConnection.Java:457)
org.Eclipse.jetty.server.HttpInput.consumeAll(HttpInput.Java:282)
   - locked [email protected]
org.Eclipse.jetty.server.HttpConnection.completed(HttpConnection.Java:360)
org.Eclipse.jetty.server.HttpChannel.handle(HttpChannel.Java:340)
org.Eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.Java:224)
org.Eclipse.jetty.io.AbstractConnection$ReadCallback.run(AbstractConnection.Java:358)
org.Eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.Java:601)
org.Eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.Java:532)
Java.lang.Thread.run(Unknown Source)

Bei näherer Betrachtung unterscheidet sich dies von den neuesten Threads mit dem folgenden Status:

Name: qtp1805176801-734
State: TIMED_WAITING on Java.u[email protected]77b83b6e
Total blocked: 5  Total waited: 478

Stack trace: 
Sun.misc.Unsafe.park(Native Method)
Java.util.concurrent.locks.LockSupport.parkNanos(Unknown Source)
Java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(Unknown Source)
org.Eclipse.jetty.util.BlockingArrayQueue.poll(BlockingArrayQueue.Java:390)
org.Eclipse.jetty.util.thread.QueuedThreadPool.idleJobPoll(QueuedThreadPool.Java:509)
org.Eclipse.jetty.util.thread.QueuedThreadPool.access$700(QueuedThreadPool.Java:48)
org.Eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.Java:563)
Java.lang.Thread.run(Unknown Source)

Basierend auf der Namenskonvention sind einige der qtp-Threads sehr alt (qtp1805176801-206), während einige sehr neu sind (qtp1805176801-6973). Ich finde es interessant, dass die älteren Threads aufgrund des 60-Sekunden-Zeitlimits keine Zeitüberschreitung aufweisen. Die Anwendung bedient Kunden während der Geschäftszeiten in den USA und ist in den frühen Morgenstunden größtenteils im Leerlauf. Zu diesem Zeitpunkt würde ich davon ausgehen, dass fast der gesamte Pool aufgeräumt wird.

In der Hoffnung, dass jemand in der Lage ist, mir die richtige Richtung aufzuzeigen, wie ich dieses Problem aufspüren kann. Meine Erfahrung mit Jetty führt mich zu der Annahme, dass ihre Inhalte sehr solide sind und die meisten Probleme entweder programmatisch in unserer Implementierung (waren dort) oder JVM-bezogen (haben das getan) sind. Seien Sie auch offen für Vorschläge, wenn Sie glauben, ich verfolge einen roten Hering auf den Fäden.

NEUE INFORMATIONEN: Wenn Sie die Ausnahmen etwas weiter verfolgen, scheint dies darauf zurückzuführen zu sein, dass GWT-RPC-Aufrufe eine Zeitüberschreitung aufweisen, während sie auf eine Antwort warten. Die folgende Stapelablaufverfolgung zeigt eine Ausnahme in der Protokolldatei, die sich auf einen Thread bezieht, der sich in einem ungültigen Zustand befindet. Hiermit können Sie andere Berichte zu Problemen mit der Jetty/GWT-Interaktion überprüfen und suchen.

2013-09-03 08:41:49.249:WARN:/webapp:qtp488328684-414: Exception while dispatching incoming RPC call
Java.io.IOException: Java.util.concurrent.TimeoutException: Idle timeout expired: 30015/30000 ms
    at org.Eclipse.jetty.util.BlockingCallback.block(BlockingCallback.Java:103)
    at org.Eclipse.jetty.server.HttpConnection$Input.blockForContent(HttpConnection.Java:457)
    at org.Eclipse.jetty.server.HttpInput.read(HttpInput.Java:130)
    at Java.io.InputStream.read(Unknown Source)
    at com.google.gwt.user.server.rpc.RPCServletUtils.readContent(RPCServletUtils.Java:175)
    at com.google.gwt.user.server.rpc.RPCServletUtils.readContentAsGwtRpc(RPCServletUtils.Java:205)
    at com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.readContent(AbstractRemoteServiceServlet.Java:182)
    at com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.Java:239)
    at com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.doPost(AbstractRemoteServiceServlet.Java:62)
    at javax.servlet.http.HttpServlet.service(HttpServlet.Java:755)
    at javax.servlet.http.HttpServlet.service(HttpServlet.Java:848)
    at org.Eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.Java:698)
    at org.Eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.Java:1506)
    at c.t.b.servlet.PipelineFilter.doFilter(PipelineFilter.Java:56)
    at org.Eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.Java:1494)
    at c.v.servlet.SetRequestEncoding.doFilter(SetRequestEncoding.Java:27)
    at org.Eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.Java:1494)
    at c.t.b.servlet.OutOfMemoryFilter.doFilter(OutOfMemoryFilter.Java:39)
    at org.Eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.Java:1486)
    at org.Eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.Java:503)
    at org.Eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.Java:138)
    at org.Eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.Java:564)
    at org.Eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.Java:213)
    at org.Eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.Java:1094)
    at org.Eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.Java:432)
    at org.Eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.Java:175)
    at org.Eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.Java:1028)
    at org.Eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.Java:136)
    at org.Eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.Java:258)
    at org.Eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.Java:109)
    at org.Eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.Java:97)
    at org.Eclipse.jetty.server.Server.handle(Server.Java:445)
    at org.Eclipse.jetty.server.HttpChannel.handle(HttpChannel.Java:267)
    at org.Eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.Java:224)
    at org.Eclipse.jetty.io.AbstractConnection$ReadCallback.run(AbstractConnection.Java:358)
    at org.Eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.Java:601)
    at org.Eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.Java:532)
    at Java.lang.Thread.run(Unknown Source)
Caused by: 
Java.util.concurrent.TimeoutException: Idle timeout expired: 30015/30000 ms
    at org.Eclipse.jetty.io.IdleTimeout.checkIdleTimeout(IdleTimeout.Java:153)
    at org.Eclipse.jetty.io.IdleTimeout$1.run(IdleTimeout.Java:50)
    at Java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
    at Java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
    at Java.util.concurrent.FutureTask.run(Unknown Source)
    at Java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(Unknown Source)
    at Java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
    at Java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at Java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at Java.lang.Thread.run(Unknown Source)
13
skimbleton

Die Frage wurde auf der Eclipse/Jetty-Website veröffentlicht. Über den folgenden Link können Sie alle permanenten Fixes für die Lösung nachverfolgen.

https://bugs.Eclipse.org/bugs/show_bug.cgi?id=416477

Das Problem hat mit dem Sperren des Semaphors für einen QTP-Thread zu tun, für den während der Anforderung im Rahmen eines GWT-RPC-Aufrufs eine Zeitüberschreitung aufgetreten ist. Die ursprüngliche Anforderung hat eine Zeitüberschreitung von 30 Sekunden. Während die Anforderung auf den Abschluss der Semaphore.acquire-Methode wartet, tritt eine Zeitüberschreitung auf. Im Rahmen der Bereinigung der Anforderung versucht die HTTP-Verbindung, .consumeAll für die Anforderung zu verwenden, wodurch erneut eine Sempahore.acquire-Anforderung versucht wird. Diesmal ist die Anforderung nicht zeitgesteuert und die Sperre bleibt bestehen, bis der Thread unterbrochen wird.

Das Problem scheint sehr plattformspezifisch zu sein, da Jetty das Problem nicht reproduzieren konnte und ich keine anderen Berichte über das Problem finden konnte. Darüber hinaus tritt dies nur in einer unserer Produktionsumgebungen auf. Ich vermute, dass zwischen dem GWT-RPC-Code, Jetty und dem Betriebssystem etwas los ist. Für das JDK, Jetty und das GWT SDK sind kleinere Upgrades geplant.

Problemumgehung Die erste Lösung bestand darin, gesperrte Threads mehrmals täglich über die JMX-Konsole manuell zu unterbrechen. Unsere längerfristige Lösung bestand darin, einen Bereinigungsmechanismus zu erstellen, der nach diesen gesperrten Threads sucht und die Interrupt-Methode für diese aufruft.

7
skimbleton

Der QueuedThreadPool ist ein gemeinsam genutzter Pool von Threads. Die darin enthaltenen Threads werden für andere Verarbeitungen wiederverwendet. Ja, die Jagd nach dem Fadenpool ist ein roter Hering, vorausgesetzt, die Fäden werden bereinigt. Diese Fäden fallen über einen langen Zeitraum langsam aus dem Becken (nachdenkliche Stunden). Dies ist eine Leistungsentscheidung im Thread-Pool (Erstellen ist teuer, tun Sie dies so selten wie möglich).

Da die Stapelspur, die Sie eingefügt haben, unvollständig ist, ist das Ausmaß der Vermutungen über das Verhalten extrem hoch. Davon abgesehen zeigen diese 2 Zeilen can normale Operationen an, aber ohne den Rest der Stapelspur gibt es wenig zu tun.

Außerdem sind die Versionen von Java, die Sie mit 1.7.0_06 und 1.7.0_11 verwenden, sehr alt und Sie sind Hunderten von Fehlerkorrekturen ausgesetzt.

1
Joakim Erdfelt

Ich habe das gleiche mit Jetty 9.2.3.v20140905 und Java (Build 1.8.0_20-b26) 64-Bit.

Problemumgehung . Installieren Sie monit http://mmonit.com/monit/

# monit.conf
check process jetty-service with pidfile "/opt/jetty-service/jetty.pid"
start program = "/usr/sbin/service jetty-service start" with timeout 30 seconds
stop program = "/usr/sbin/service jetty-service stop"
if totalmem is greater than 1268 MB for 10 cycles then restart
if 5 restarts within 5 cycles then timeout
1
sytolk