2010-03-15 8 views
4

Initialement publié on Server Fault, où il a été suggéré que cette question pourrait être mieux posée ici.débogage JBoss 100% de l'utilisation du processeur

Nous utilisons JBoss pour exécuter deux de nos WAR. L'un est notre application Web, l'autre est notre service Web. L'application Web accède à une base de données sur une autre machine et envoie des demandes au service Web. Le service Web envoie des demandes JMS à d'autres machines, agrège les données et les renvoie.

Chez notre plus gros client, environ une fois par mois, le processus JBoss Java prend 100% de tous les processeurs. La machine qui exécute JBoss a 8 processeurs. Notre application Web est toujours accessible pendant cette période, mais le chargement des pages prend environ 3 minutes. Redémarrer JBoss restaure tout à la normale.

La base de données et toutes les autres machines fonctionnent correctement, seule la machine exécutant JBoss est affectée. L'utilisation de la mémoire est normale. L'utilisation du réseau est normale. Il n'y a aucun message d'erreur suspect dans les journaux JBoss. J'ai installé un environnement de test aussi proche que possible de l'environnement de production du client et j'ai effectué des tests de charge avec deux fois plus d'utilisateurs simultanés. Je n'ai pas obtenu mon environnement de test pour reproduire le problème.

Où allons-nous d'ici? Comment pouvons-nous réduire le problème? Actuellement, le seul plan que nous avons est d'attendre que le problème apparaisse en production, puis de déboguer pour en déterminer la cause. Jusqu'à présent, les gens ont juste redémarré JBoss quand le problème est survenu pour minimiser le temps d'arrêt. La prochaine fois que cela arrivera, ils auront un développeur pour jeter un coup d'oeil. La question est, la prochaine fois que cela arrive, que peut-on faire pour déterminer la cause?

Nous pourrions installer une instance JBoss distincte sur la même boîte et installer l'application Web séparément du service Web. De cette façon, lorsque le problème surviendra, nous saurons quelle WAR a le problème (en supposant que c'est notre code). Cela ne le réduit pas beaucoup cependant.

Dois-je activer la télécommande JMX? De cette façon, la prochaine fois que le problème se produit, je peux me connecter avec VisualVM et voir quels threads prennent le CPU et ce qu'ils font. Cependant, y a-t-il un inconvénient important à l'activation de JMX remote dans un environnement de production?

Existe-t-il une autre façon de voir quels threads mangent le processeur et d'obtenir une pile pour voir ce qu'ils font?

D'autres idées?

Merci!

+0

Bonjour. Avez-vous trouvé la cause du problème avec JBoss? Nous avons le même problème de temps en temps. –

+2

Oui, désolé pour le retard. Nous avions un HashMap écrit par deux threads simultanément. Si un put déclenche un rehash, le second put peut faire pointer deux nœuds de carte l'un vers l'autre. Le prochain get sur le HashMap déclenchera une boucle infinie. – NateS

Répondre

2

Je pense que vous devriez certainement essayer de mettre en place un environnement de test avec quelques tests de charge afin de reproduire votre problème. Le profilage aiderait définitivement à cerner le problème.

Une solution rapide serait de tuer jboss avec kill -3 la prochaine fois afin d'obtenir une image à analyser. La deuxième chose que je vérifie est que vous utilisez des drapeaux -server et que vos paramètres gc sont sains. Vous pouvez également exécuter dstat pour voir ce que le processus fait pendant le blocage. Mais encore une fois - il est probablement plus sûr de simplement configurer un environnement de test de charge (via EC2 ou plus) pour le reproduire.

+0

J'ai une configuration d'environnement de test et j'utilise The Grinder pour le marteler. Je suis incapable de reproduire le problème là. Pas certain de pourquoi. Peut-être que mes tests n'exercent pas la même ou une grande variété de données. J'ai profilé mes tests pour être sûr qu'il n'y a normalement pas de conflit de threads. J'ai trouvé que la production n'utilisait pas -server, et j'ai crié à quelqu'un pour cela. :) Les paramètres GC sont les paramètres par défaut. Est-ce si mauvais? Je vais certainement vérifier les commandes que vous avez énumérées. – NateS

+0

+1 pour la vidange de fil –

+0

Désolé Nate, raté la section de test de charge dans votre message. J'ai vraiment besoin de commencer à lire les messages avant de leur répondre :) –

3

Cela se produit typiquement avec du code d'emballement ou un accès non sécurisé aux hashmaps. Un simple vidage de thread (kill -3, comme dit @disown, ou ctrl-break dans une console Windows) révélera ce problème.

Comme vous ne parvenez pas à le reproduire en utilisant des tests, je pense que ça sent comme un problème de simultanéité; Il est généralement difficile de faire en sorte que les scripts de test se comportent de manière suffisamment aléatoire pour détecter les problèmes de ce type. J'essaye normalement de faire la procédure standard d'opération pour faire des bourrelets de fil de n'importe quelle JVM qui est redémarrée en raison d'anomalies fonctionnelles, et c'est vraiment une obligation d'attraper ces choses une fois par mois.

7

Il existe un moyen simple et rapide d'identifier les threads qui utilisent le temps CPU sur JBoss. Allez dans la console JMX avec un navigateur (habituellement sur http://localhost:8080/jmx-console, mais peut être différent pour vous), cherchez un bean appelé ServerInfo, il a une opération appelée listThreadCpuUtilization qui déverse le temps CPU réel utilisé par chaque thread actif, dans un joli tableau format. S'il y a un mauvais comportement, il se distingue généralement comme un pouce endolori.

Il existe également l'opération listThreadDump qui vide la pile pour chaque thread dans le navigateur.

Pas aussi bon qu'un profileur, mais un moyen beaucoup plus facile d'obtenir les informations de base. Pour les serveurs de production, c'est souvent une mauvaise nouvelle de connecter un profileur, c'est très pratique.

+0

J'ai vérifié cela. C'est très utile! Bien que vous deviez utiliser des noms de thread plutôt que des ID pour corréler entre la liste d'utilisation du processeur de thread et les chemins d'accès de threads. – NateS

+1

Juste utilisé ceci pour suivre quelque chose dans notre environnement. Merci. – mwilson