Мы используем JBoss для запуска двух наших WAR. Одно - это наше веб-приложение, другое - наш веб-сервис. Веб-приложение обращается к базе данных на другом компьютере и делает запросы к веб-службе. Веб-служба отправляет JMS-запросы на другие машины, объединяет данные и возвращает их.
У нашего крупнейшего клиента примерно раз в месяц Java-процесс JBoss занимает 100% всех процессоров. Машина, на которой запущен JBoss, имеет 8 процессоров. Наше веб-приложение все еще доступно в это время, однако загрузка страниц занимает около 3 минут. Перезапуск JBoss восстанавливает все до нормального состояния.
Машина базы данных и все остальные машины в порядке, только машина, на которой запущен JBoss, затронута. Использование памяти нормальное. Использование сети нормальное. В журналах JBoss нет сообщений о подозрительных ошибках.
Я настроил тестовую среду как можно ближе к производственной среде клиента и провел нагрузочное тестирование с двукратным увеличением числа одновременно работающих пользователей. У меня нет тестовой среды для воспроизведения проблемы.
Куда мы отправимся отсюда? Как мы можем сузить проблему?
В настоящее время единственный план, который у нас есть, - это дождаться, пока проблема возникнет сама по себе в производственной среде, а затем выполнить некоторую отладку, чтобы определить причину. До сих пор люди только что перезапустили JBoss, когда возникла проблема, чтобы минимизировать время простоя. В следующий раз, когда это произойдет, они попросят разработчика взглянуть. Вопрос в том, что можно сделать, чтобы определить причину, когда это произойдет в следующий раз?
Мы могли бы установить отдельный экземпляр JBoss на том же компьютере и установить веб-приложение отдельно от веб-службы. Таким образом, когда проблема возникнет в следующий раз, мы будем знать, в какой WAR возникла проблема (при условии, что это наш код). Однако это не сильно сужает его.
Стоит ли включать JMX Remote? Таким образом, в следующий раз, когда возникнет проблема, я смогу подключиться к VisualVM и посмотреть, какие потоки используют процессор и что, черт возьми, они делают. Однако есть ли существенный недостаток включения JMX Remote в производственной среде?
Есть ли другой способ увидеть, какие потоки потребляют процессор, и получить трассировку стека, чтобы увидеть, что они делают?
Есть другие идеи?
Спасибо!
Вы можете отправить сигнал SIGQUIT на работающую JVM, чтобы получить трассировку стека каждого потока на стандартный вывод. Это не убивает процесс, хотя я думаю, что он переводит все потоки в спящий режим, пока печатаются трассировки стека.
Затем сопоставьте перечисленные идентификаторы потоков с предпочитаемым методом просмотра загрузки ЦП по потокам. prstat -L
для Solaris, top -H
для Linux. Обратите внимание, что tid в трассировке стека Java печатаются в шестнадцатеричном формате; вам, вероятно, придется преобразовать в десятичный формат при сравнении с выводом top или prstat.
Дамп делаю. Однако в моих производственных системах это невозможно сделать, если JVM не запущена с определенными параметрами, которые мы никогда не включим в производственной среде. В этом случае я использую jboss.system: type = ServerInfo mbean консоли JMX для создания дампа потока (listThreadDump ()).
Когда я еще не написал код, вывод дампа потока для меня практически не имеет смысла. Но человек, написавший код, может понять его смысл. В тех случаях, когда дампы потоков не помогают, я предпочитаю использовать "strace -fp <PID of JBoss' java process> -o outfile.txt
«чтобы по-другому взглянуть на происходящее на уровне системных вызовов. Это немного похоже на питье из пожарного шланга, но иногда это помогает.