Problèmes liés aux threads
Voici quelques-uns des scénarios qui indiquent des problèmes de performances ou de stabilité de votre application ThingWorx :
De nombreux threads bloqués pendant une longue période
Conflit de ressources partagées
Threads dont l'exécution s'éternise
Cette section donne une présentation de ces types de problème.
Threads bloqués
De nombreux threads bloqués pendant une longue période révèlent un conflit de ressources élevé au niveau de la JVM ou un blocage possible. Lorsque plusieurs threads sont bloqués et sont dans l'attente d'une ressource partagée, par exemple l'accès à une base de données, les utilisateurs sont généralement bloqués et empêchés d'exécuter des opérations.
Un conflit important se résout parfois de lui-même. Par exemple, lorsqu'une volumineuse opération d'écriture dans une base de données s'achève. Toutefois, si les threads restent bloqués pendant une longue période :
Il peut exister une situation de blocage, à savoir que les threads se verrouillent les uns les autres dans une répétition circulaire.
Ou, il se peut qu'une seule transaction occasionne de blocage, parce qu'elle ne termine pas le traitement dans le temps requis.
Vous pouvez vérifier ce problème comme suit :
Recherchez le nombre de threads bloqués.
Vérifiez si le thread qui est bloqué dans un instantané reste bloqué dans les instantanés suivants.
L'image suivante illustre un thread bloqué :
Dans cet exemple, l'opération de dézippage dans TWEventProcessor-10 est bloquée. Elle attend qu'une autre opération de dézippage se termine dans le thread TWEventProcessor-9. Deux utilisateurs peuvent dézipper les fichiers au même moment dans ThingWorx, et le deuxième utilisateur doit attendre que le premier termine l'opération. Les deux opérations accèdent à un objet 0x2f9a4f4 qui est verrouillé dans TWEventProcessor-9.
Si de nombreux threads de processeur d'événements sont également bloqués, des problèmes de stabilité du serveur plus importants peuvent exister. En outre, le sous-système de traitement des événements peut afficher une augmentation du nombre de threads actifs. Par ailleurs, sa file d'attente d'événements non traités ne cesse d'augmenter si le scénario bloqué ne se résout pas rapidement.
Conflit de ressources partagées
Les threads d'événements et de base de données dans ThingWorx peuvent constituer un goulet d'étranglement des performances pour les raisons suivantes :
Vérifiez s'il existe un conflit au niveau des groupes de threads C3P0PooledConnectionPoolManager et TWEventProcessor. La présence d'un grand nombre de threads bloqués ou de threads qui travaillent activement dans ces catégories peut révéler un goulot d'étranglement de performances potentiel.
Il se peut que des événements soient mis en file d'attente sur le serveur si tous les threads de base de données et d'événement sont occupés.
Prenons l'exemple suivant : Dans le cas présent, un thread d'événement bloque tous les threads de connecteur de base de données. Le thread d'événement 11 dans la pile d'appels effectue une mise à jour volumineuse de la base de données.
"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
La logique des services personnalisés exécutant l'opération peut être optimisée, comme illustré dans l'exemple ci-dessous :
"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 dont l'exécution s'éternise
Les threads dont l'exécution s'éternise sont une indication que le code personnalisé de votre application ThingWorx peut nécessiter une optimisation. Les transactions utilisateur classiques s'exécutent rapidement au niveau de la JVM, en une fraction de seconde ou en quelques secondes. Toutefois, un thread dont l'exécution s'éternise, par exemple pendant plus de 10 minutes et impliquant un code personnalisé peut indiquer un problème. Collectez plusieurs instantanés de threads sur un intervalle de 10 minutes pour connaître la durée d'exécution d'une opération sur un thread spécifique.
Par exemple, une capture pendant un intervalle de 60 minutes affiche le même modèle d'exécution sur le même thread :
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)

Dans cet exemple, le thread effectue un tri sur une table d'informations. L'opération de tri se poursuit tout en itérant chaque élément dans une grande table d'informations. Cette opération peut être optimisée de sorte qu'elle se produise une seule fois à la fin. Les opérations qui s'éternisent créent un conflit au niveau de la mémoire, de la base de données ou d'autres ressources serveur. Par conséquent, il est important d'identifier et de remédier aux services qui prennent trop de temps dans votre application personnalisée ThingWorx.