К содержанию
SemCue

Art Quest · Horror Cinema · Morpheus · инфраструктура

Облако упало в 03:31.Через сутки — штатный режим.

8 октября в зоне Yandex Cloud, где стоял единственный сервер, пропало питание. Вместе с ним у компании остановились сайты квестов, хоррор-кинотеатра и театра, онлайн-бронирование, боты, прием заявок в CRM и финансовый учет. Снимков диска не было. Мы подняли все на новом сервере у другого провайдера, а данные собрали заново из выгрузок и внешних сервисов.

Работает · новый сервер с 8 октября, ежедневные копии за его пределами с 9 октября 2026

Авария питания в зоне облака. Все сайты и боты недоступны
Первая волна сайтов на новом сервере с рабочим HTTPS
Брони, бонусы и сертификаты импортированы после бэкапа
Аварийный режим снят, проверка: 45 из 45

Что упало

В 03:31 по Ташкенту (в Омске было 04:31) провайдер открыл инцидент: нарушение электропитания в зоне доступности. На этой зоне стоял один сервер, и на нем держалось почти все: три сайта, бронирование с онлайн-оплатой, боты в Telegram, VK и MAX, дашборд, зарплата и Cash Flow, отчеты клиентам SemCue.

Позже в тот же день упала облачная функция, через которую сайты и боты отправляли заявки в amoCRM. Она была у того же провайдера.

Публичная страница статуса Yandex Cloud: нарушение электропитания в зоне доступности ru-central1-b, статус Unavailable, история обновлений с 3:31 до 10:26 по GMT+5
Публичная страница статуса провайдера, снимок 8 октября, 15:02 по Ташкенту. Фрагменты: заголовок инцидента и история обновлений.

До 8 октября

  • Один сервер в одной зоне облака. На нем сайты трех бизнесов, бронирование, боты, дашборд и учет.
  • Снимков диска не было. Регулярные копии лежали на том же диске, за его пределами — только разовые старые копии части данных.
  • Заявки принимала облачная функция у того же провайдера, и она упала вслед за сервером.
  • Мониторинг жил на том же сервере, поэтому про аварию он сообщить уже не мог.
  • Часть кода существовала только на сервере и не была в git.

После переезда

  • Новый сервер у другого провайдера, больше памяти и swap.
  • Каждый день копия баз, данных и настроек уходит за пределы сервера и принимается только после проверки контрольных сумм.
  • Прием заявок перенесен на свой сервер: тот же код, тот же контракт, без облачной функции.
  • Состояние основных сервисов сохранено в git на следующий день после переезда.
  • Мониторинг пересобран скриптами, плюс smoke-проверка всего контура одной командой.
Слабые места были известны и раньше. Авария просто проверила их все за одну ночь.

Сначала план, потом сервер

Ждать, пока зона поднимется, было нельзя: провайдер не давал сроков, а брони на выходные никто не отменял. Пока компания покупала новый сервер, мы собрали пакет развертывания с нуля.

В пакете оказалась опись каждого сервиса: как запускается, какие порты, данные и интеграции. Для кода аналитики, самого большого проекта, лучший источник каждого файла выбрали среди git, рабочих копий и старых снимков и подтвердили контрольными суммами. Выяснилось неприятное: около 400 файлов существовали только в образе на упавшем сервере. Еще в пакет вошли шаблоны настроек (только имена переменных, без значений), скрипты установки и план запуска в четыре уровня, у каждого свои проверки и откат.

  • Уровень 1

    Сайты и HTTPS

    Статические сайты, маршрутизация, сертификаты. Проверка до смены DNS запросами прямо на новый адрес.

  • Уровень 2

    Бронь, оплата, заявки

    Сервис бронирования, платежи ЮKassa, прием заявок. Без ключей магазина Horror не переключали.

  • Уровень 3

    Боты и дашборд

    Telegram, VK, MAX. Состояния ботов с проверкой целостности при старте.

  • Уровень 4

    Учет и отчеты

    Зарплата, Cash Flow, отчеты клиентам, мониторинг.

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

Две волны DNS и аварийный режим

Сертификаты и маршруты проверили еще до переключения DNS: новый сервер отвечал с временными сертификатами, а запросы шли прямо на его адрес. Потом первая волна: девять адресов, среди них сайты Art Quest и Morpheus, бонусы, статус и SemCue. Проверка шла из Москвы, Петербурга, Германии и США с настоящими сертификатами Let’s Encrypt. Для каждой записи был готов машиночитаемый откат. С этой же волной на сайтах включился аварийный режим.

Horror Cinema переключили второй волной, после того как компания внесла ключи магазинов ЮKassa и отдельно согласовала переключение. Пока онлайн-бронь не работала, на сайтах висела плашка и форма заявки менеджеру. Форма записывала каждую заявку на диск до ответа, отсекала ботов и повторы и пропускала не больше 5 заявок в минуту с одного адреса. Уведомление об оплате сервер подтверждал только после сверки платежа через API, иначе просил ЮKassa повторить позже.

Сайт Art Quest в аварийном режиме: плашка о восстановлении и форма заявки менеджеру вместо онлайн-брони
Аварийный режим на сайте Art Quest, 8 октября утром. Онлайн-бронь временно заменена формой, заявка не теряется.

Данные без старого диска

Код восстановить проще всего. Сложнее с данными: брони, бонусы гостей, подарочные сертификаты, зарплатный журнал. Последние полные копии лежали на том же диске. Снимок старого диска так и не удалось сделать: 39 попыток заканчивались ошибками облака, а еще 36 попыток просто остановить машину получали ответ «сервис перегружен».

Поэтому данные собирали из того, что было на руках, по правилам, которые согласовали с компанией заранее. Главное правило: если баланс неизвестен, его нельзя ни обнулить, ни угадать.

Что было на руках

Выгрузка бронейпоследняя копия от 23 сентября
amoCRMсделки с датами и контактами за последние недели
ЮKassaоплаченные платежи и возвраты по трем магазинам
Переписка ботов VKпо сообщениям бота видно, кому и когда начислялись бонусы
Google Calendarживой календарь сеансов

Правила компании

Неизвестный баланс не обнулять и не угадыватьспорное уходит на ручную проверку
Повторные начисления не суммироватьодно событие — одно начисление
Погашенный сертификат не возвращать в активныедаже если источник старый
Сообщение об оплате не равно зачислениюденьги подтверждает только платеж
У каждой записи источник и контрольная суммаимпорт только после копии текущих данных

Что получилось

220 броней192 из копии от 23 сентября, 27 из снимка аналитики за 15 часов до аварии (контакты из CRM у 22 из них), 1 новая
Реестр подарочных сертификатовсобран заново по платежам ЮKassa
Бонусные кошельки ботоввосстановлены из последней выгрузки и сообщений бота по правилам слева
Не всечасть данных последних недель восстановить было не из чего; это записано в журнале
Импорт в рабочую систему 8 октября в 16:12 по Ташкенту, после копии текущих данных. У каждой восстановленной записи есть ссылка на источник.

Днем случился сюрприз. Старый сервер ожил и снова начал опрашивать Telegram теми же ключами ботов. Два сервера тянули одни и те же сообщения и мешали друг другу. Помог только перевыпуск токенов.

Три потока работ и один журнал

Работа шла в три потока одновременно. Первый поднимал сервер, боты и приложения. Второй восстанавливал данные. Третий переключал DNS, публиковал отчеты клиентам и пытался снять снимок старого диска.

Чтобы потоки не мешали друг другу, все действия записывались в общий журнал с временем по UTC, Ташкенту и Омску. Правила простые: каждый поток пишет только в свою папку, копирует, а не перемещает, ничего не удаляет, у каждой папки опись и контрольные суммы. Оплаты, рассылки и DNS — только после явного «да» от компании.

Ошибки тоже записаны. Например, контейнер прокси держал старую версию файла настроек, и команда перезагрузки молча не применяла правки. После этого правило поменяли: перезапуск контейнера и проверка, что изменение действительно вступило в силу.

  1. Провайдер открывает инцидент: перебои питания в зоне облака. Сервер недоступен снаружи.

  2. Задача: собрать полный пакет запуска на новой инфраструктуре. Любое действие с рабочими системами — только после «да» от компании.

  3. Новый сервер отвечает, но ключ доступа не привязан. Пароль не подбираем, ждем, пока компания добавит ключ.

  4. Первая волна DNS: 9 адресов работают на новом сервере с доверенным HTTPS, проверка из Москвы, Петербурга, Германии и США. На сайтах аварийный режим: плашка и форма заявки.

  5. Оплаты: ключи магазинов ЮKassa внесены, уведомления принимаются только после сверки через API. Движок брони запущен на живом календаре.

  6. Начинаются попытки снять снимок старого диска: 39 попыток, ошибки облака. Потом 36 попыток хотя бы остановить машину. Снимка так и нет.

  7. Вторая волна DNS: Horror Cinema, отчеты, профили. Все 13 адресов работают на новом сервере.

  8. Импорт данных после копии текущих: 220 броней, состояния ботов, 33 сертификата.

  9. Облачная функция заявок тоже недоступна. Прием заявок переносится на свой сервер, 48 ссылок в 38 файлах сайтов переключены.

  10. Мониторинг пересобран скриптами: 61 проверка, активные — в норме.

  11. Старая машина частично ожила и опрашивает Telegram теми же ключами ботов. Два сервера мешают друг другу.

  12. Ключи ботов перевыпущены. Через минуту конфликтов ноль.

  13. Штатный режим для сайтов и бронирования: плашки сняты, проверка всего контура — 45 из 45.

  14. Пробное восстановление ночных архивов сервера из полного снимка: 53 файла данных читаются без ошибок.

  15. Шестая ежедневная копия подряд принята после проверки контрольных сумм. Сеть пять раз обрывала скачивание, через полчаса скрипт начал заново.

Время по Ташкенту (UTC+5). Из общего журнала переезда и журнала резервных копий.

Что изменилось после

В ночь на 9 октября сайты и бронирование вернулись в штатный режим, итоговая проверка прошла по всем 45 пунктам. Дальше мы занялись тем, из-за чего авария оказалась такой болезненной.

  • 6 из 6ежедневных копий баз, данных и настроек за пределами сервера приняты после проверки9–14 октября, по контрольным суммам
  • 61проверка в мониторинге пересобрана скриптамиуведомления в Telegram
  • 53файла данных прочитались после пробного восстановления ночных архивов сервера9 октября, без ошибок

Вернуть удалось не все: часть данных последних недель восстановить было не из чего. Что именно потеряно, записано в журнале переезда, а не спрятано. Код основных сервисов синхронизирован с боевым сервером, а копия проверяется не только на наличие: 14 октября сеть пять раз подряд обрывала скачивание, через полчаса скрипт начал заново и принял копию только после проверки контрольных сумм.

Как это делалось

Решения за компанией, работа — наша

Компания выбирала, что поднимать первым, и провайдера, вводила ключи и давала «да» на каждое действие с деньгами, клиентами или DNS. Мы готовили пакет, поднимали сервисы, переключали записи и собирали данные.

За пять недель до этого был отдельный эпизод: сайты тормозили, и разбор нашел две разные причины. Зациклившийся одноразовый служебный контейнер съедал половину процессора, а проверка здоровья календаря каждую минуту скачивала весь календарь. После исправления медленные ответы этой проверки ускорились с 4,784 до 0,341 секунды, а ложные ошибки 502, которых было 5 760 за сутки, прекратились. Та же привычка: сначала доказанная причина, потом ремонт.

  • КомпанияПриоритеты запуска, выбор провайдера, ключи и пароли, разрешения на оплаты, рассылки и DNS.
  • SemCueПакет развертывания, новый сервер, боты, аварийный режим, DNS и сертификаты волнами, восстановление броней, бонусов, сертификатов и зарплатного журнала, итоговая проверка.

Для технических читателей

Как устроено

Пакет развертывания
Опись сервисов, выбор лучшего источника кода по контрольным суммам, шаблоны настроек без секретов, скрипты установки, план запуска в четыре уровня, сценарий на случай, если старый сервер вернется.
Переключение
Проверка сертификатов и маршрутов до смены DNS, две волны с наблюдением, машиночитаемый откат, проверка из нескольких стран.
Аварийный режим
Плашка на всех страницах и прием заявок с записью на диск до ответа, отсечением ботов, лимитами и защитой от повторов. Уведомления об оплатах принимались только после сверки с ЮKassa.
Прием заявок
Облачная функция заменена небольшой оберткой на своем сервере, которая вызывает тот же код без изменений и с тем же таймаутом.
Данные
Восстановление из копий и внешних API с источником и контрольной суммой у каждой записи. Импорт только после копии текущего состояния.
После
Ежедневная копия баз, данных приложений и настроек за пределами сервера с проверкой контрольных сумм и ротацией, мониторинг из скриптов, проверка всего контура одной командой.

Откуда цифры

Каждая цифра на странице взята из рабочих документов

Следующая система

Подарочные сертификаты с оплатой и личной ссылкой →

SemCue / Обсудим задачу

Что вы хотите изменить?

Расскажите о проекте и задаче. Даже если пока есть только идея.

Напишите нам в Telegram

Обсудим цель, текущую ситуацию и подходящий следующий шаг.

Обсудить проект в Telegram
В разработкеСайт ещё дорабатывается: что-то может меняться.