Три способа не узнать о своей аварии
Разбор инженерной литературы по надёжности дал не технологию, а классификацию уже случившегося. Способов не узнать оказалось ровно три, и все три были представлены у нас инцидентами с датами.
- Никто не спрашивает. Сервис лежит, состояние его никем не опрашивается — сбой обнаружит первый, кому сервис понадобился. Так умирал сервер и так же тихо стояла сломанная выкладка.
- Спрашивает, но глотает ответ. Скрипт наткнулся на недоступный источник, молча продолжил и выдал правдоподобное число, посчитанное по неполным данным.
- Спрашивать нечего и некого. Единственная копия данных: узнать о проблеме получится ровно один раз, и это будет уже не сигнал, а последствие.
Прибор, который спрашивает сам
Первую дыру закрыли почасовой проверкой живости. Опрашиваются пять целей: сайт, личный кабинет, API админки, приёмник заявок и доступ к серверу по служебному каналу. Устройство простое, но три решения в нём приняты не по умолчанию.
- Два замера с паузой в 20 секунд, а не один. Одиночный промах сети не должен поднимать тревогу — иначе оповещение перестают читать через неделю.
- Сигнал идёт на смену состояния, а не на каждый неуспешный опрос: падение — одно сообщение, восстановление — одно. Поток одинаковых строк про то же падение равен молчанию.
- Длительности меряются монотонными часами. Настенные часы могут шагнуть назад при синхронизации времени, и тогда замер выдаёт отрицательную или дикую величину.
Проверка прогнана вживую: все пять целей зелёные, ветки падения и восстановления проверены симуляцией отказа, а не рассуждением о правильности кода. Оповещение уходит владельцу на телефон, без настроенного канала — в консоль и в код возврата: беззвучного режима нет.
Почему падение — это подозрение, а не факт
Университетский курс по распределённым системам добавил к монитору оговорку: идеального детектора сбоя в реальной сети не существует. Таймаут не отличает «умер» от «медленно отвечает», ложные срабатывания заложены в конструкцию, а не в качество реализации.
Практических следствий два, и оба вошли в процедуру. Тревога поднимается после нескольких неуспешных опросов подряд, а не после первого. Первый шаг по тревоге — перепроверка другим способом, руками, а не перезапуск сервиса: рестарт по ложному сигналу превращает исправную систему в неисправную.
Экономика доступности, которую полезно посчитать до строительства. Доступность в 99 % означает 3,7 дня простоя в год, 99,9 % — 8,8 часа. Нашему контуру двух-трёх девяток достаточно, а инженерия пяти девяток означала бы плату за то, чего никто не заметит. Дешёвый прибор, ловящий многочасовые падения, закрывает реальный риск целиком.
Молчаливый пропуск источника
Второй способ не узнать об аварии дороже первого, потому что выглядит как успех. Отчёт от 21 июня собирал данные из нескольких выгрузок и одну из них молча пропустил — ту, что появилась позже остальных. Ни ошибки, ни предупреждения: сводка построена по неполному набору и выглядела совершенно нормальной.
Ошибка тут не в конкретном скрипте, а в стиле: недоступный вход обрабатывался как пустой. Правило формулируется одной строкой — инструмент обязан заявлять о недоступном источнике и падать, а не подставлять ноль. Ноль — утверждение о мире («событий не было»), и подменять им «я не смог посмотреть» нельзя.
Честно о статусе. Правило записано в канон и применяется в новом коде, но сплошного аудита старых инструментов на молчаливый пропуск мы не делали: класс ошибки закрыт для того, что пишется сейчас, и не закрыт для написанного раньше.
Самый тихий риск — единственная копия
Третий пункт списка стоял первым по риску: 14 из 16 репозиториев жили на одном диске без внешней копии — сайты, история заказов, инструменты в одном экземпляре. Формулировка из первой главы книги про надёжность не оставляет места оптимизму: единственная копия данных превращает вопрос «потеряем ли» в вопрос «когда». Промежуточных сигналов у риска нет: падение сервиса можно заметить и починить, отказ единственного диска даёт сразу конечное состояние. Прибор тут не помогает — помогает только вторая копия в другом месте.
Работа запущена в тот же вечер: заводятся закрытые внешние репозитории и выгружаются все ветки, а не только основная — по нашему же правилу инструмент, оставленный на невлитой ветке, это инструмент, которого нет. Пункт стоит со статусом «в работе», и «закрыто» мы не пишем до подтверждения по каждому репозиторию.
Что закрыто и чем это проверено
| Пункт | Состояние | Чем подтверждено |
|---|---|---|
| Сбой прода и сервера находит человек | закрыто | живой прогон по пяти целям; падение и восстановление проверены симуляцией отказа |
| Тревога по одному промаху сети | закрыто | два замера с паузой 20 секунд |
| Длительность по настенным часам | закрыто в приборе | монотонные часы |
| Молчаливый пропуск источника | частично | правило в каноне, аудита старых нет |
| Единственная копия репозиториев | в работе | подтверждение по каждому не собрано |
| Планировщик привязан к запущенному окружению | открыто | обход не сделан |
Последняя строка — та самая, которую хочется не писать. Сторож, живущий на включённом компьютере владельца, закрывает падение в рабочее время и не закрывает ночь; до внешнего независимого пинга закрытие частичное.