Отказ веб-сервиса: порядок реагирования

Регламент действий при недоступности размещённого сервиса — от подтверждения оповещения до подтверждения восстановления

v1 0 stars 0 forks 0 watchers 1 branch 0 runs Public
mikicreated via APIv1

Когда применять. Получено оповещение о недоступности веб-сервиса либо отказ замечен самостоятельно.

Порядок построен так, чтобы каждый шаг отсекал целый класс причин, а не проверял наугад. Пропуск первых трёх шагов — самая частая потеря времени: диагностируют приложение, когда недоступна сеть.

1. Подтверждение оповещения

1
Проверить сетевую доступность рабочей станции

Прежде чем диагностировать сервер, убедиться, что маршрут до него существует.

Why: Обрыв связи у рабочей станции внешне неотличим от отказа сервера. Диагностика и устранение при этом принципиально разные.
$curl -s -o /dev/null -w '%{http_code}\n' https://github.com
Check
  • Код 200 — связь есть, продолжать
  • Пустой ответ — устранять связь, сервер ни при чём
2
Проверить работоспособность системы мониторинга

Открыть status.equiply.ru. При её отказе в Telegram поступает отдельное оповещение от watchdog.

Why: uptime-kuma и ntfy размещены на одном сервере. При его отказе замолкают оба, и отсутствие оповещений становится неотличимо от штатной работы.
$curl -s -o /dev/null -w '%{http_code}\n' https://status.equiply.ru
Check
  • Мониторинг отвечает — оповещению можно доверять
  • Не отвечает — наблюдение за сайтами прекращено, это самостоятельный инцидент
3
Проверить сервис из второй точкиRecommended

Мониторинг наблюдает мир из одной точки. Рабочая станция — вторая независимая.

Why: Недоступность сервиса и недоступность маршрута от сервера мониторинга — разные инциденты, требующие разных действий.
$curl -sS -o /dev/null -w 'код %{http_code}, время %{time_total}s\n' https://ДОМЕН
Check
  • Результат совпал с оповещением — отказ подтверждён
  • Сервис открывается — проверять маршрут от мониторинга, а не сервис

Масштаб определяет объект восстановления. Один домен — восстанавливается приложение. Несколько доменов одного сервера — восстанавливается сервер, поочерёдная проверка сайтов бессмысленна.

2. Оценка масштаба

4
Определить масштаб по заголовку оповещения

Заголовок содержит ответ: «netcup: не отвечают 3 из 16 сайтов» либо «ttinv.ru не отвечает».

Why: Группировка по серверу введена именно для этого: при отказе netcup недоступны четырнадцать доменов, и четырнадцать раздельных оповещений скрыли бы существо инцидента.
Check
  • Указан сервер — переходить к серверу
  • Указан домен — переходить к его проекту
5
Уточнить состав сервера по рееструRecommended
Why: Работоспособность соседних сервисов исключает отказ сервера целиком и вдвое сужает область поиска.
$python3 -c "import yaml,pathlib; d=yaml.safe_load(pathlib.Path('/home/mike/Projects/arch-hq/registry/servers.yml').read_text()); [print(s['name'], [x['host'] for x in (s.get('sites') or [])]) for s in d['servers']]"

3. Идентификация проекта

6
Определить репозиторий по домену

Задача уже создана в репозитории затронутого проекта, в её тексте перечислено всё семейство.

Why: Домену соответствует несколько репозиториев: devon-pro — три, setfork — шесть. Без полного перечня отказ серверной части ищут в клиентской.
$repo-for --all ДОМЕН
Check
  • Возвращён arch-hq — репозиторий не установлен, диагностика только по логам

4. Подключение к серверу

7
Подключиться по SSH

Параметры доступа находятся в ~/.ssh/config и порождаются из реестра серверов.

Why: Ключи и конфигурация подготовлены заранее — поиск доступов во время инцидента исключён.
$ssh netcup # либо servicest4, brave
Check
  • Подключение не устанавливается — перейти к шагу о недоступности сервера
8
Действия при недоступности SSHOptional

Остаётся панель управления хостингом и перезагрузка. Ссылки на панели в реестре ОТСУТСТВУЮТ — известный пробел.

Why: Перезагрузка — крайняя мера: она уничтожает состояние, по которому устанавливается причина. Применять после исчерпания остальных способов.
A person is needed here: This depends on real-world experience — add yours. answer from experience

5. Установление причины

9
Выявить нездоровые контейнеры
Why: Контейнер может находиться в состоянии Up и при этом не обслуживать запросы; признак healthy эту разницу показывает.
$docker ps --format '{{.Names}}\t{{.Status}}' | grep -v healthy
Check
  • Контейнер отсутствует в выводе — он не запущен, проверить docker ps -a
10
Изучить журнал отказавшего контейнера
Why: Причина отказа фиксируется в конце журнала; начало занято загрузкой зависимостей.
$docker logs --tail 200 --timestamps КОНТЕЙНЕР 2>&1 | tail -60
Check
  • Искать строки error, failed, denied, exit code
  • Журнал пуст — проверить docker inspect КОНТЕЙНЕР --format '{{.State}}'
11
Проверить дисковое пространство и памятьRecommended
Why: Значительная доля отказов без очевидной причины вызвана исчерпанием дискового пространства. Проверка обходится дешевле построения гипотез.
$df -h / && free -m && docker system df
Check
  • Свободно менее 10% — причина установлена
12
Проверить связь с недавним развёртываниемRecommended
Why: Первый вопрос при отказе — не вызван ли он последним изменением. Недавно запущенный контейнер отвечает на него немедленно.
$docker ps --format '{{.Names}}\t{{.RunningFor}}' | sort -k2

Дальнейшие действия принимает человек. Ниже перечислено допустимое, а не предписанное. Автоматическое восстановление промышленной среды не применяется: видов отказа много, а сценарий автоматического исправления один.

6. Восстановление

13
Перезапустить сервисOptional

Наименее затратное действие, если причина в зависшем процессе, а не в коде.

Why: Тома с кэшами сохраняются при перезапуске и уничтожаются при пересоздании.
A person is needed here: This depends on real-world experience — add yours. answer from experience
$docker compose restart СЕРВИС
Check
  • НЕ применять docker compose down — приводит к потере томов и кэшей
  • НЕ применять docker system prune без фильтра
14
Внести исправление в кодOptional

Исправить в локальной копии, отправить в main. Развёртывание выполняется автоматически.

Why: Правка непосредственно на сервере утрачивается при следующем развёртывании и не попадает в историю изменений.
A person is needed here: This depends on real-world experience — add yours. answer from experience

7. Подтверждение восстановления

15
Дождаться оповещения о восстановлении

Мониторинг фиксирует восстановление и направляет отдельное сообщение.

Why: Без подтверждения возможно продолжение работ над сервисом, восстановившимся самостоятельно, и ошибочное отнесение результата к принятым мерам.
Check
  • Оповещение не поступило в течение 5 минут — проверить сервис вручную
16
Закрыть задачу с указанием причины

В том репозитории, где она создана. Указать установленную причину и выполненные действия.

Why: Закрытые задачи образуют статистику отказов. По ней через месяц видно, какие отказы повторяются, — а это и определяет, что подлежит исправлению в первую очередь.
$gh issue close НОМЕР -R mikey-semy/РЕПОЗИТОРИЙ -c 'причина: … ; выполнено: …'

Не реализовано на текущий момент — перечень приводится намеренно:

  • ссылки на панели управления хостингом для случая недоступности SSH
  • учёт ложных срабатываний: каждое падение считается новым
  • окно тишины на время развёртывания — собственное изменение способно вызвать оповещение
  • приоритет по владельцу: простой клиентского сервиса равнозначен собственному

Пересмотр — после месяца эксплуатации. Фиксировать следует не то, что сработало, а то, чего недоставало в момент инцидента.