Потоки JBoss, ожидающие на случайном мониторе

Я делаю некоторое тестирование загрузки на веб-приложении, развернутом в JBoss. Это запускает прекрасный, но поскольку тест растет, и больше смоделированных пользователей начинает поражать JBoss, производительность ухудшается сильно:

Resposne time chart

Подключая VisualVM к нему, я вижу, что потоки были всем штрафом, затем внезапно запущенный провести большую часть их времени, ожидая монитора (зеленый работает, красный монитор, желтый ожидание):

Thread state graph

Работая jstack, я вижу, что потоки все ожидают в том же месте:

"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]

Большинство ~200 потоков процессора HTTP ожидает того же монитора. Смотря на log4j.xml для ВОЙНЫ, это имеет единственную установку appender для КОНСОЛИ. Я удаляю appender и пробую мой тест снова. То же поведение, кроме jstack показывает все потоки, ожидающие в другом месте:

"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]

Ничего не изменяя, я перезапускаю JBoss, запускаю тест, затем выполняю jstack, после того как это становится медленным. Все потоки ожидают во все же другом месте:

"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]

Что в heck продолжается? Я использовал jstack в прошлом, и я пытался выполнить его, когда вещи хорошо работают и получили ожидаемые результаты. Я предполагаю, что jstack прекрасен. Какие-либо идеи, что могло вызвать такое странное поведение? Какие-либо идеи о том, куда пойти отсюда?

7
задан Glorfindel 31 July 2019 в 09:06
поделиться

2 ответа

Я настроил приложение в Tomcat, работающем через Eclipse, и не увидел проблемы. В конце концов я обнаружил, что мы запускаем JBoss с помощью 32-битной оболочки службы Windows, хотя мы использовали 64-битный JDK. Машина была 64-битной. Я не уверен, как это вообще будет работать? В любом случае, переход на 32-битный JDK избавил меня от сумасшедшей проблемы, и я смог жить дальше.

2
ответ дан 7 December 2019 в 12:14
поделиться

Подобного поведения следовало ожидать.Увеличивая масштаб нагрузочного теста, вы всегда будете находить узкие места, а в сложной системе эти узкие места будут меняться.

Ваша задача - выявить эти узкие места и попытаться исправить их по очереди. Каждый раз, когда вы это делаете, вы всегда будете находить другой, но, надеюсь, система с каждым разом будет лучше масштабироваться. Это непросто, но тогда нелегко масштабировать под нагрузку.

  • Возьмем ваш 1-й пример. У вас много вызовов метода log4j Logger.debug () . Log4j плохо работает при входе в систему под нагрузкой, поэтому вам нужно принять некоторые меры предосторожности. Даже если в вашей конфигурации log4j указано «не записывать сообщения DEBUG», log4j все равно придется поработать, прежде чем это осознать. Рекомендуемый подход к обработке - заключать каждый вызов Logger.debug () в if Logger.isDebugEnabled () {Logger.debug (); } `блок. Это должно устранить это узкое место.

  • В вашем 2ndexample вы вызываете метод XOM Node.query () . Этот метод должен перекомпилировать выражение XPath при каждом вызове, и это кажется узким местом. Найдите API, в котором вы можете предварительно скомпилировать выражение XPath и повторно использовать его.

  • В третьем примере вы читаете файл . Это не лучшая идея для высоконагруженной системы, file-io работает медленно, когда вы выполняете большое количество небольших операций. Подумайте о повторной реализации этого, чтобы работать по-другому, если сможете.

Все они не связаны между собой, но все присутствующие узкие места производительности вы увидите при масштабировании под нагрузку. Вы никогда не избавитесь от них всех, но, надеюсь, вы сможете довести дело до того уровня, когда это будет достаточно хорошо.

3
ответ дан 7 December 2019 в 12:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: