Запишите диагностику приостановленной анимации Spring Boot

Spring Boot

Перепечатано из моего блога

Оригинальный адрес: 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 в основном нормальные, и все они находятся в состоянии парковки.

Thread

Это довольно странно, продолжайте задаваться вопросом, вызвал ли 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.

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, но на самом деле общий объем кучи невелик.

mat

Проанализировав количество потоков, оно составляет около 240, что мало чем отличается от нормы. И во многом это временная нить во сне.

Суммировать

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