Каков ваш алгоритм действий при возникновении критической ошибки (паники) в продакшене?

Ответ

При возникновении критической ошибки в продакшене главное — действовать быстро, системно и без паники. Алгоритм можно разделить на несколько этапов:

1. Стабилизация системы (Triage & Stabilization)

  • Немедленный откат: Если сбой произошел сразу после выката новой версии, самое быстрое решение — откатить развертывание до предыдущей стабильной версии.
  • Отключение функционала: Если проблема связана с конкретной функцией, можно временно отключить ее с помощью feature flag (флага функциональности), не затрагивая остальную часть системы.

2. Сбор информации и диагностика (Investigation)

  • Анализ логов: Изучить централизованные логи (например, в ELK Stack, Loki) на предмет сообщений об ошибках, паниках и их стектрейсов. panic в Go обычно логируется автоматически.
  • Анализ метрик: Проверить дашборды мониторинга (Grafana) на аномалии: всплески CPU/memory, количество ошибок, время ответа.
  • Воспроизведение в тестовом окружении: Попытаться воспроизвести ошибку на staging- или dev-среде, чтобы безопасно ее отладить. Для этого пишутся минимальные воспроизводимые примеры или интеграционные тесты.

3. Поиск и устранение причины (Root Cause Analysis & Fix)

  • Отладка: Используйте дебаггер, например, dlv (Delve), для пошагового анализа кода.
  • Профилирование: Если проблема связана с производительностью или утечками, используйте pprof для анализа CPU, памяти и горутин.
  • Детектор гонок (Race Detector): Скомпилируйте и запустите приложение с флагом -race в тестовой среде, чтобы выявить потенциальные состояния гонки.
  • Восстановление после паники: В критически важных горутинах можно использовать recover для перехвата паники, чтобы она не привела к падению всего приложения. Важно залогировать ошибку и стек вызовов перед завершением горутины.
    defer func() {
    if r := recover(); r != nil {
        log.Printf("PANIC recovered: %vn%s", r, debug.Stack())
    }
    }()

4. Развертывание исправления и постмортем (Deploy & Post-mortem)

  • После исправления и тщательного тестирования выкатить новую версию.
  • Провести постмортем — анализ инцидента с командой, чтобы понять, почему он произошел и как предотвратить подобные проблемы в будущем (например, улучшить покрытие тестами, добавить новые алерты).

Ответ 18+ 🔞

Ну вот, опять всё накрылось медным тазом в продакшене, а ты сидишь и думаешь, как бы так красиво обосраться, чтобы начальство не заметило. Забудь. Тут надо действовать быстро, без истерик, но и без понтов. Слушай сюда, распишу по шагам, как не просрать всё окончательно.

1. Срочно останови этот пиздец (Стабилизация) Первым делом — не дай системе сдохнуть окончательно.

  • Откати нахуй назад: Если всё полетело сразу после того, как ты впиндюрил новую версию — это знак. Знак, что ты мудак. Быстро откатывай развертывание к прошлой, рабочей версии. Это как кнопка «вернуть всё как было» после того, как ты нахуйрил в код.
  • Выруби фичу: Если проблема в какой-то одной новой функции — убей её. Используй feature flag (флаг функциональности), чтобы просто отключить эту пиздопроебибну, не трогая весь остальной сервис. Типа «ой, этой кнопки тут никогда и не было».

2. Найди, кто во всём виноват (Диагностика) Паника — не повод бегать кругами. Включи голову.

  • Ройся в логах: Лезь в свои ELK Stack или куда ты там логи скидываешь. Ищи слова panic, fatal, error. Стектрейс — твой лучший друг, он покажет, в каком именно месте код решил, что жить дальше не стоит.
  • Смотри на графики: Открой Grafana и посмотри, что там творится. CPU зашкаливает? Память уплыла в космос? Количество ошибок подпрыгнуло, как хуй на морозе? Метрики не врут.
  • Повтори это говно у себя: Попробуй воспроизвести ошибку на тестовом стенде. Создай минимальный пример, который ломается. Если получится — уже полдела сделано, можно ковыряться в безопасности.

3. Почини эту хуйню (Поиск причины и исправление) Вот тут начинается магия. Или кринж. Смотря как повезёт.

  • Дебаггер в руки: Бери dlv (Delve) и пошагово гоняй код. Смотри, где он начинает гнать пургу.
  • Профилирование — твой отец: Если всё тормозит или память течёт — включай pprof. Он покажет, какая функция жрёт процессор или память, как сука.
  • Детектор гонок (Race Detector): Скомпилируй приложение с флагом -race и запусти в тестовой среде. Он может выявить такие скрытые состояния гонки, что ты сам от себя охуеешь. «А оно, блядь, так работало?»
  • Перехват паники (recover): В самых критичных горутинах можно поставить recover, чтобы они не тянули за собой всё приложение. Но это не индульгенция! Обязательно залогируй, что случилось, и стек вызовов, а потом аккуратно заверши эту горутину. Чтобы хотя бы знать, от чего сдохло.
    defer func() {
    if r := recover(); r != nil {
        log.Printf("ОЙ БЛЯДЬ, ПАНИКА! Восстановил: %vnСтек: %s", r, debug.Stack())
        // Тут можно что-то сделать, но осторожно, епта
    }
    }()

4. Выкати исправление и сделай работу над ошибками

  • Починил? Протестировал? Выкатывай, блядь. Но уже без того фанатизма.
  • Обязательно проведи постмортем. Собери команду и разберите, какого хуя это произошло. Цель — не найти крайнего и выебать его, а понять системную причину. Может, тестов не хватает? Может, алерты молчали? Напиши план: «Чтобы такого больше не повторилось». Иначе через месяц наступишь на те же грабли, только в профиль.

Вот и весь сказ. Главное — не суетиться как мартышлюшка, а делать всё по шагам. И да, следующий раз перед выкатом в прод думай головой, а не жопой.