Перепечатано из моего блога
Оригинальный адрес: https://www.deanwangpro.com/2019/07/28/zombie-thread-trouble-shooting
В последние два дня я столкнулся с проблемой приостановления службы, специфическое явление заключается в том, что служба больше не получает никаких запросов, а клиент выдает Broken Pipe.
Проверить состояние системы
Выполните top и обнаружите, что загрузка процессора и памяти не высока, но через команду
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
Нашел много БЛИЗКИХПорт WAIT занят, продолжайте вызывать API службы и найдите CLOSE после ожидания тайм-аута.Количество WAITов тоже не выросло, а значит сервис почти мертв.
Проверить ситуацию с JVM
Подозревая, что поток может зайти в тупик, я решил сначала сбросить ситуацию с потоком и выполнить
jstack <pid> > /tmp/thread.hump
Обнаружено, что потоки tomcat в основном нормальные, и все они находятся в состоянии парковки.
Это довольно странно, продолжайте задаваться вопросом, вызвал ли GC STW, используйтеjstat
Проверить сбор мусора
app@server:/tmp$ jstat -gcutil 1 2000 10
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0.00 27.79 65.01 15.30 94.75 92.23 1338 44.375 1881 475.064 519.439
Когда я это увидел, я был в шоке: количество FGC фактически превышало количество YGC с продолжительностью 475 секунд. Должна быть какая-то причина для запуска FGC, но, к счастью, мы включили журнал GC.
Обнаружено, что полный сборщик мусора, вызванный сбоем распределения, часто происходит в течение определенного периода времени. Тем более, что на использование райской зоны тоже приходится немалая доля.Учитывая, что частые новые объекты убегают на старость, это вызовет проблемы. Я спросил о развитии бизнеса, и подтвердил, что есть API внешней стыковки без пейджинга, и после запроса может быть сгенерировано большое количество объектов.
Поскольку внешний API временно не может связаться с другой стороной для модификации, чтобы сначала решить проблему, исходный MaxNewSize увеличивается со 192 МБ до двойного. После нескольких дней наблюдения было обнаружено, что gc в основном имеет тенденцию к норме.
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0.00 3.37 60.55 8.60 95.08 92.98 87 2.421 0 0.000 2.421
Куча была сброшена перед расширением
jmap -dump:format=b,file=heapDump <PID>
Анализируя утечку памяти через MAT, можно предположить, что это класс в jdbc, но на самом деле общий объем кучи невелик.
Проанализировав количество потоков, оно составляет около 240, что мало чем отличается от нормы. И во многом это временная нить во сне.
Суммировать
На самом деле это расследование не нашло настоящей причины, косвенная видимость заключается в том, что FGC часто приводила к зависанию сервиса. Кроме того, порт привода работает нормально, из-за чего процесс проверки работоспособности ошибочно полагает, что служба работает нормально, и тревога не срабатывает. Если вы столкнулись с похожей ситуацией, пожалуйста, обсудите вместе.