Probleme mit Threads
Unten finden Sie einige der Szenarios, die auf Leistungs- oder andere Stabilitätsprobleme in Ihrer ThingWorx Lösung hinweisen:
Viele blockierte Threads über einen langen Zeitraum
Konflikte mit gemeinsam genutzten Ressourcen
Threads mit langer Ausführungszeit
Dieser Abschnitt enthält eine Übersicht über diese Problemtypen.
Blockierte Threads
Viele blockierte Threads über einen langen Zeitraum weisen auf einen umfangreichen Ressourcenkonflikt auf JVM-Ebene oder einen potenziellen Deadlock hin. Wenn zahlreiche Threads blockiert sind und auf eine gemeinsam genutzte Ressource warten, z.B. auf Datenbankzugriff, können Benutzer normalerweise keine Operationen durchführen.
Umfangreiche Konflikte lösen sich manchmal selbst. Beispielsweise, wenn eine große Datenbank-Schreiboperation abgeschlossen wird. Wenn die Threads jedoch über einen längeren Zeitraum blockiert bleiben:
Es gibt möglicherweise eine Deadlock-Situation, d.h., dass Threads einander in einem kreisförmigen Muster sperren.
Oder es kann eine einzelne blockierende Transaktion geben, die die Verarbeitung in der erforderlichen Zeit nicht abschließt.
Sie können dieses Problem prüfen, indem Sie:
nach der Anzahl der blockierten Threads suchen
prüfen, ob der in einem Schnappschuss blockierte Thread in den nachfolgenden Schnappschüssen blockiert bleibt
Die folgende Abbildung zeigt einen blockierten Thread:
In diesem Beispiel ist die Entpacken-Operation in TWEventProcessor-10 blockiert. Sie wartet darauf, dass eine andere Entpacken-Operation im Thread TWEventProcessor-9 abgeschlossen wird. Zwei Benutzer können die Dateien gleichzeitig in ThingWorx entpacken, und der zweite Benutzer wartet darauf, dass der erste den Vorgang abschließt. Beide Operationen greifen auf das Objekt 0x2f9a4f4 zu, das in TWEventProcessor-9 gesperrt ist.
Wenn auch viele Ereignisprozessor-Threads blockiert sind, kann es zu größeren Serverstabilitätsproblemen kommen. Außerdem kann die Anzahl aktiver Threads im Untersystem für die Ereignisverarbeitung erhöht sein. Die Warteschlange mit unverarbeiteten Ereignissen wächst ebenfalls, wenn die Blockierung nicht schnell behoben wird.
Konflikte mit gemeinsam genutzten Ressourcen
Die Datenbank- und Ereignis-Threads in ThingWorx können aus den folgenden Gründen zu einem Leistungsengpass führen:
Prüfen Sie die Konflikte für die Gruppe C3P0PooledConnectionPoolManager und TWEventProcessor von Threads. Eine große Anzahl blockierter Threads oder Threads, die aktiv in diesen Kategorien arbeiten, kann auf einen potenziellen Leistungsengpass hinweisen.
Möglicherweise sind Ereignisse in der Warteschlange auf dem Server vorhanden, wenn alle Datenbank- und Ereignis-Threads belegt sind.
Betrachten Sie das folgende Beispiel. In diesem Fall sperrt ein Ereignis-Thread alle Datenbank-Konnektor-Threads. Der Ereignis-Thread 11 im Aufrufstapel führt eine große Datenbank-Aktualisierungsoperation durch.
"C3P0PooledConnectionPoolManager[identityToken->2v1py89n68drc71w36rx7|68cba7db]-HelperThread-#7" tid=0xa0 in BLOCKED
Blocked: 414717[-1ms], Waited: 416585[-1ms]
User CPU: 5s320ms
at java.lang.Object.wait(Native Method)
- waiting on <0x56978cbf> (a com.mchange.v2.async.ThreadPoolAsynchronousRunner), held by TWEventProcessor-11
"C3P0PooledConnectionPoolManager[identityToken->2v1py89n68drc71w36rx7|68cba7db]-HelperThread-#6" tid=0x9f in BLOCKED
Blocked: 415130[-1ms], Waited: 416954[-1ms]
User CPU: 5s530ms
at java.lang.Object.wait(Native Method)
- waiting on <0x56978cbf> (a com.mchange.v2.async.ThreadPoolAsynchronousRunner), held by TWEventProcessor-11
Die Logik der benutzerdefinierten Dienste, die die Operation durchführen, kann optimiert werden, wie im folgenden Beispiel gezeigt:
"TWEventProcessor-11" tid=0x92 in RUNNABLE
Blocked: 3913[-1ms], Waited: 37924[-1ms]
User CPU: 45s430ms
at com.thingworx.persistence.common.sql.SqlDataTableProvider.updateEntry(SqlDataTableProvider.java:13)
at com.thingworx.persistence.TransactionFactory.createDataTransactionAndReturn(TransactionFactory.java:155)
at com.thingworx.persistence.common.BaseEngine.createTransactionAndReturn(BaseEngine.java:176)
Threads mit langer Ausführungszeit
Threads mit langer Ausführungszeit geben an, dass der benutzerdefinierte Code in Ihrer ThingWorx Lösung möglicherweise eine Optimierung erfordert. Typische Benutzertransaktionen werden schnell auf JVM-Ebene abgeschlossen, in Sekundenbruchteilen oder Sekunden. Ein Thread mit langer Ausführungszeit, z.B. mehr als 10 Minuten, der einen benutzerdefinierten Code umfasst, kann auf ein Problem hinweisen. Sammeln Sie mehrere Thread-Schnappschüsse über ein 10-minütiges Intervall, um zu sehen, wie lange eine Operation für einen bestimmten Thread dauert.
Beispiel: Eine Erfassung während eines 60-minütigen Intervalls zeigt dasselbe Ausführungsmuster auf demselben Thread an:
http-nio-8443-exec-25" tid=0xc7 in RUNNABLE
Blocked: 750[-1ms], Waited: 8866[-1ms]
User CPU: 1h35m
- synchronizer <0x35153c2f> (a java.util.concurrent.ThreadPoolExecutor$Worker)
at com.thingworx.types.data.sorters.GenericSorter.compare(GenericSorter.java:93)
at com.thingworx.types.data.sorters.GenericSorter.compare(GenericSorter.java:20)
at java.util.TimSort.countRunAndMakeAscending(TimSort.java:360)
at java.util.TimSort.sort(TimSort.java:234)
at java.util.Arrays.sort(Arrays.java:1512)
at java.util.ArrayList.sort(ArrayList.java:1454)
at java.util.Collections.sort(Collections.java:175)
at com.thingworx.types.InfoTable.quickSort(InfoTable.java:722)

Im Beispiel führt der Thread eine Sortierung in einer Infotable durch. Die Sortieroperation wird fortgesetzt, während sie jedes Element in einer großen Infotable durchläuft. Die Operation kann so optimiert werden, dass sie einmal am Ende erfolgt. Operationen mit langer Ausführungszeit erzeugen Konflikte entweder auf Arbeitsspeicherebene, auf Datenbankebene oder auf anderen Serverressourcen. Daher ist es wichtig, Dienste mit langer Ausführungszeit in Ihrer benutzerdefinierten ThingWorx Lösung zu identifizieren und zu adressieren.
War dies hilfreich?