2010-06-29 2 views
7

Je fais des tests de charge sur une application web déployée dans JBoss. Il démarre bien, mais comme les rampes d'essai vers le haut et les utilisateurs plus simulés commencer à frapper JBoss, les performances se dégradent sévèrement:JBoss threads en attente sur un moniteur aléatoire

Resposne time chart http://i46.tinypic.com/2mob2f9.jpg

Connexion VisualVM à elle, je peux voir les fils étaient bien, puis tout à coup commencé à dépenser la plupart de leur temps d'attente pour un moniteur (vert est en cours d'exécution, le rouge est le moniteur, le jaune est attente):

Thread state graph http://i46.tinypic.com/105v6lk.jpg

Courir jstack, je vois les fils sont tous en attente dans le même endroit:

"http-0.0.0.0-8080-172" daemon prio=6 tid=0x000000005da90000 nid=0xd2c waiting for monitor entry [0x000000006cb4e000] 
    java.lang.Thread.State: BLOCKED (on object monitor) 
    at org.apache.log4j.Category.callAppenders(Category.java:185) 
    - waiting to lock (a org.apache.log4j.spi.RootCategory) 
    at org.apache.log4j.Category.forcedLog(Category.java:372) 
    at org.apache.log4j.Category.debug(Category.java:241) 
    [my code]

La plupart des threads du processeur HTTP ~ 200 attendent le même moniteur. En regardant log4j.xml pour le WAR, il a une configuration d'appender unique pour CONSOLE. Je supprime l'appender et recommence mon test. Même comportement, à l'exception jstack montre tous les fils d'attente dans un endroit différent:

"http-0.0.0.0-8080-251" daemon prio=6 tid=0x0000000059811800 nid=0x1108 waiting for monitor entry [0x0000000073ebe000] 
    java.lang.Thread.State: BLOCKED (on object monitor) 
    at java.util.Hashtable.get(Hashtable.java:333) 
    - waiting to lock (a org.jboss.util.property.PropertyMap) 
    at java.util.Properties.getProperty(Properties.java:932) 
    at org.jboss.util.property.PropertyMap.getProperty(PropertyMap.java:626) 
    at java.lang.System.getProperty(System.java:653) 
    at org.jaxen.saxpath.helpers.XPathReaderFactory.createReader(XPathReaderFactory.java:109) 
    at org.jaxen.BaseXPath.(BaseXPath.java:124) 
    at org.jaxen.BaseXPath.(BaseXPath.java:153) 
    at nu.xom.JaxenConnector.(JaxenConnector.java:49) 
    at nu.xom.Node.query(Node.java:424) 
    [my code]

rien changer, je redémarre JBoss, exécutez le test, puis exécutez jstack une fois qu'il est lent. Tous les fils attendent encore dans un autre lieu:

"http-0.0.0.0-8080-171" daemon prio=6 tid=0x000000005d0d1000 nid=0x15d4 waiting for monitor entry [0x000000006cb4e000] 
    java.lang.Thread.State: BLOCKED (on object monitor) 
    at sun.nio.cs.FastCharsetProvider.charsetForName(FastCharsetProvider.java:118) 
    - waiting to lock (a sun.nio.cs.StandardCharsets) 
    at java.nio.charset.Charset.lookup2(Charset.java:449) 
    at java.nio.charset.Charset.lookup(Charset.java:437) 
    at java.nio.charset.Charset.isSupported(Charset.java:479) 
    at sun.nio.cs.StreamDecoder.forInputStreamReader(StreamDecoder.java:49) 
    at java.io.InputStreamReader.(InputStreamReader.java:57) 
    at java.io.FileReader.(FileReader.java:41) 
    [my code]

Que dans le diable se passe? J'ai utilisé jstack dans le passé et j'ai essayé de l'utiliser quand les choses tournent bien et j'ai obtenu les résultats attendus. Je suppose que jstack va bien. Des idées qui pourraient causer un tel comportement étrange? Des idées sur où aller à partir d'ici?

+0

Sans plus de contexte/d'information, il est difficile de dire précisément ce qui se passe. En général, il semble qu'il y ait beaucoup de conflits pour diverses ressources et/ou une situation de blocage possible. Comme votre première étape, il semble que vous avez supprimé une partie de la contention pour log4j. Est-il possible de faire la même chose pour les deux autres ressources en combinant des résultats de requête de mise en cache ou en synchronisant l'accès à des structures de données pouvant mener à un blocage? – btreat

+0

Je suis heureux de fournir plus d'informations, je ne suis pas sûr de ce qu'il faut fournir. Chose étrange, bien qu'il y ait beaucoup de conflits, les threads ne sont pas bloqués. Ils attendent sur un moniteur pendant 2 à 10 secondes et plus, puis l'exécution continue, puis peu de temps après l'attente sur un moniteur. Les appels sont très basiques (par exemple System.getProperties) et ne peuvent pas être évités. JBoss et d'autres codes tiers font ces appels. Puisque je suis assez sûr que System.getProperties et HashTable sont solides, ma prochaine estimation est que jstack est trompeur quand la contention se produit. Si oui, comment pourrais-je déterminer où se situe la contention? – NateS

Répondre

2

J'ai configuré l'application dans Tomcat à travers Eclipse et je n'ai pas vu le problème. Finalement, j'ai découvert que nous commencions JBoss en utilisant un wrapper de service Windows 32 bits, même si nous utilisions un JDK 64 bits. La machine était 64 bits. Je ne suis pas sûr comment cela fonctionnerait même? En tout cas, passer à un JDK 32 bits a fait disparaître le problème fou et j'ai pu continuer ma vie.

3

Ce type de comportement est à prévoir. Au fur et à mesure que vous intensifiez un test de charge, vous allez toujours trouver des goulots d'étranglement, et dans un système complexe, ces goulets d'étranglement vont se déplacer.

Votre travail consiste à identifier ces goulets d'étranglement et à essayer de les résoudre, un à la fois. Chaque fois que vous le faites, vous en trouverez toujours un autre, mais nous espérons que le système évoluera mieux à chaque fois. Ce n'est pas facile, mais la mise à l'échelle pour la charge n'est pas facile.

  • Prenez votre premier exemple. Vous avez beaucoup d'appels à la méthode Logger.debug() de log4j. Log4j ne fonctionne pas bien lors de la connexion sous charge, vous devez donc prendre quelques précautions. Même si votre configuration log4j dit "ne pas enregistrer les messages DEBUG", log4j doit encore faire un peu de travail avant de s'en rendre compte. L'approche recommandée pour gérer est d'enrouler tous les appels Logger.debug() dans un if Logger.isDebugEnabled() {Logger.debug(); } `bloc. Cela devrait changer ce goulot d'étranglement particulier.

  • Dans votre deuxième exemple, vous appelez la méthode Node.query() de XOM. Cette méthode doit recompiler l'expression XPath à chaque appel, ce qui semble être un goulot d'étranglement. Trouvez une API où vous pouvez pré-compiler l'expression XPath et la réutiliser. Dans le 3ème exemple, vous lisez un File. Ce n'est pas une bonne idée dans un système à forte charge, le fichier-io est lent lorsque vous effectuez un grand nombre de petites opérations. Pensez à ré-implémenter cela pour travailler différemment si vous le pouvez.

Tous ces éléments sont sans rapport, mais tous les goulots d'étranglement actuels de performance que vous verrez lors du redimensionnement de la charge. Vous ne vous débarrasserez jamais de tous, mais j'espère que vous pourrez l'atteindre à un point où cela sera suffisant.

+0

Je ne vois pas de goulots d'étranglement. Log4j appelle (en écrivant même dans un fichier en série), appelle System.getProperty, et en appelant Charset.isSupported sont des opérations rapides, pas normalement les appels qui doivent être évités. Je ne fais que 250 threads. Ces serrures sont normalement lâchées très rapidement. Plus de 100 threads en attente sur System.getProperty signifie que le thread bloquant le HashTable prend beaucoup de temps. Le thread de verrouillage appelle simplement Hashtable.get. Il y a peu de raisons pour que cela prenne beaucoup de temps. Peut-être que jstack est trompeur? Cela semble peu probable, car il ne montre pas de threads bloquants lorsque l'application Web fonctionne correctement. – NateS

+0

@NateS: Ils peuvent être des opérations rapides, mais ils sont mono-thread, et cela les rend goulots d'étranglement. Peu importe à quelle vitesse ils sont, ils ne sont pas concurrents. Vos propres décharges de pile le prouvent. – skaffman

+0

Je ne peux pas croire qu'un programme de test simple qui avait 250 threads tous appelant System.getProperties montrerait les mêmes problèmes de contention que je vois avec mon application. – NateS

Questions connexes