Продакшн упал в 23:58 в новогоднюю ночь — и я пропустил бой курантов
Есть вопросик)))
В этой индустрии есть негласный закон: если что-то может сломаться в самый неподходящий момент — оно сломается именно тогда. Новогодняя ночь — идеальный момент для проверки этого закона.
Я работал в финтех-компании. Мы делали платёжный шлюз. Нагрузка в новый год — одна из пиковых: все переводят деньги, покупают подарки в последний момент, пьют шампанское и одновременно пытаются провести транзакцию.
31 декабря, примерно в 22:00 я сидел у родителей. Оливье, телевизор, ощущение что ты наконец человек, а не придаток к ноутбуку. Дежурство официально было у Димы. Я был «вторым уровнем».
В 23:58 мне позвонил Дима. Голос у него был такой, что я сразу встал из-за стола и вышел в коридор.
— Макс, у нас лежит. Всё. Payment gateway не отвечает. Метрики нормальные, сервисы запущены, но транзакции не проходят.
Я открыл ноутбук прямо в коридоре, на тумбочке с телефонным аппаратом эпохи СССР. Зашёл в Grafana — всё зелёное. CPU нормальный, память нормальная, сетевой трафик... стоп. Входящий — есть. Исходящий — ноль. Абсолютный ноль. Сервисы запущены, слушают порты, принимают соединения — но ничего не отправляют в ответ.
В это время в телевизоре начали бить куранты. Моя мама заглянула в коридор с бокалом шампанского. Я сделал жест «одну минуту» — что в нашей профессии означает «от тридцати минут до нескольких часов».
Нашёл проблему через двадцать две минуты нового года. Оказалось, в 23:55 сработал cron-job, который запускался раз в год 31 декабря для «очистки годовых логов». Скрипт удалял log-файлы старше 365 дней — разумная идея. Но через glob-паттерн он также захватывал конфигурационный файл SSL-сертификатов. Сертификаты физически никуда не делись, но конфиг, который указывал на них — исчез. Nginx перечитал конфигурацию и тихо перестал устанавливать TLS-соединения с upstream банковским API, требовавшим mutual TLS.
Фикс занял четыре минуты: восстановить конфиг из git, перезапустить nginx, убедиться что транзакции пошли.
Я вернулся к столу в 00:31. Шампанское было тёплым. Оливье съели без меня.
А тот cron-job мы заменили нормальным logrotate с явными паттернами. И добавили тест: после каждого cron-задания запускается smoke-test платёжной цепочки. Каждую ночь. Включая 31 декабря.ии. Знает только что был большой скандал и несколько уволенных.
В нашей команде после этой истории появился CI-шаг: grep по всему коду на паттерны TODO.*прод, TODO.*prod, REMOVE BEFORE, DEBUG ONLY. Если находит — пайплайн падает с ошибкой. Работает без единого ложного срабатывания уже полтора года.
Recommended Comments