Короткий ответ
Характерные признаки на дашбордах: резкий синхронный рост трафика (rate(requests_total)) на нескольких зависимых сервисах одновременно без соответствующего роста реального пользовательского трафика на входе, рост latency и ошибок по цепочке "снизу вверх" и высокая доля запросов, помеченных как retry (если она инструментирована отдельным label).
Как это работает подробнее
когда нижележащий сервис (например, база данных или внешний API) начинает отвечать медленно или с ошибками, вызывающие сервисы с настроенными retry начинают повторять неудачные запросы, что увеличивает нагрузку на уже перегруженный сервис — нагрузка растёт лавинообразно (retry storm), что может довести до полной недоступности даже после восстановления исходной причины, так как накопленные повторные запросы продолжают "бомбить" систему.
Пример кода
# Трафик на входе системы (API gateway)
rate(gateway_requests_total[1m])
# Трафик между внутренними сервисами к зависимости
rate(internal_requests_total{target="payment-service"}[1m])Что использовать на практике
- Практика. ключевой диагностический сигнал — сравнение входящего трафика на границе системы (внешний API gateway) с внутренним трафиком между сервисами: если внутренний трафик вырос в разы сильнее внешнего, это явный маркер retry storm. Для предотвращения в будущем используют экспоненциальный backoff с джиттером, ограничение максимального числа retry и circuit breaker, который временно прекращает попытки к явно деградировавшей зависимости.
- Практика. Если первый график держится на обычном уровне (100 req/s), а второй вырос с 150 req/s до 3000 req/s за несколько минут без изменения внешнего трафика, это прямое указание на retry storm внутри системы, а не на реальный рост пользовательской нагрузки — дальше нужно искать, какой сервис-потребитель настроен с агрессивным retry без backoff.
Подводные камни
- Частые ошибки. при расследовании смотреть только на конечный симптом (сервис С недоступен) и не проверять, не вызван ли избыточный трафик к нему повторными попытками от сервисов А и Б; добавлять retry без ограничения и backoff "для надёжности", что при реальном сбое превращает временную деградацию в полный отказ; не инструментировать retry отдельной метрикой (
http_client_retries_total), из-за чего retry storm незаметен до тех пор, пока не станет критическим.