DeadlockDebugger <http://plone.org/products/deadlockdebugger/> est un produit Zope permettant d'afficher, à un instant donné, l'état des différents threads d'une instance Zope.
Ce produit a été développé initialement par Nuxéo pour Python 2.3/2.4 (Zope de 2.7 à 2.10) et vient d'être porté par Pilot Systems pour Python 2.6 et 2.7 (Zope 2.12 et 2.13). La dernière version se trouve sur notre site de contributions.
L'utilisation du produit se déroule en 3 étapes :
On obtient alors une liste de l'activité des différents threads du Zope, du type (pour un Zope au repos) :
Threads traceback dump at 2014-03-03 16:09:17 Thread 140425561179904: File "/usr/lib/zope2.13/lib/python/Zope2-2.13.20.egg/ZServer/PubCore/ZServerPublisher.py", line 25, in __init__ name, a, b=accept() File "/usr/lib/zope2.13/lib/python/Zope2-2.13.20.egg/ZServer/PubCore/ZRendezvous.py", line 73, in accept l.acquire() Thread 140425569572608: File "/usr/lib/zope2.13/lib/python/Zope2-2.13.20.egg/ZServer/PubCore/ZServerPublisher.py", line 25, in __init__ name, a, b=accept() File "/usr/lib/zope2.13/lib/python/Zope2-2.13.20.egg/ZServer/PubCore/ZRendezvous.py", line 73, in accept l.acquire() Thread 140425586358016: File "/usr/lib/zope2.13/lib/python/Zope2-2.13.20.egg/ZServer/PubCore/ZServerPublisher.py", line 25, in __init__ name, a, b=accept() File "/usr/lib/zope2.13/lib/python/Zope2-2.13.20.egg/ZServer/PubCore/ZRendezvous.py", line 73, in accept l.acquire() Thread 140425577965312: File "/usr/lib/zope2.13/lib/python/Zope2-2.13.20.egg/ZServer/PubCore/ZServerPublisher.py", line 25, in __init__ name, a, b=accept() File "/usr/lib/zope2.13/lib/python/Zope2-2.13.20.egg/ZServer/PubCore/ZRendezvous.py", line 73, in accept l.acquire() End of dump
Note : il est conseillé d'utiliser directement l'adresse du Zope, sans passer par d'éventuels frontaux (Apache, Squid/Varnish, Haproxy/Pound, ...) afin d'éviter une éventuelle congestion à leurs niveaux.
Attention : les informations contenues dans les tracebacks peuvent être confidentielles, il est donc important de bien garder le mot de passe secret.
L'utilisation première, pour laquelle il a été inventé, est de trouver les raisons du blocage d'une instance Zope, qui ne répond plus aux demandes. DeadlockDebugger intercepte le ZPublisher très tôt et peut donc répondre même si les 4 (ou autres) threads du Zope sont tous bloqués.
Les cas de blocage d'un Zope peuvent être, par exemple :
Dans ce cas, afficher lors du blocage l'état des threads permettra de détecter facilement la cause du blocage.
La deuxième manière d'utiliser le produit est pour analyser et corriger, lors du développement, une requête particulièrement lente. En faisant un dump rapide de l'état du Zope pendant qu'il traite la requête, il est possible de voir à quel niveau survient la lenteur. Une ligne de commande du type :
while true; do lynx -dump http://<host>:<port>/manage_debug_threads?<SECRET> >> deadlock-debug.log ; done
Une variante consiste à faire tourner, régulièrement, dans un cron (ou assimilé) un dump du DeadlockDebugger et d'analyser ensuite, après plusieurs jours, le contenu du log pour trouver les parties du code à optimiser en priorité (opération de profilage).
Attention tout de même, en raison du fonctionnement des threads sous Python, les appels systèmes (lecture/écriture, gestion des verrous, ...) seront surreprésentés dans le résultat du DeadlockDebugger. Il n'est pas pertinent de regarder à trop bas niveau (code interne de Zope) les résultats, mais plus au niveau intermédiaire (code des produits d'extension).
Ce petit produit très pratique permet d'adresser différents soucis d'exploitation ou de performance dans des développements Zope (ou Plone).
Actions sur le document