Разработка отказоустойчивого веб-сервиса: резервирование и восстановление

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

Обследование — 200 000 ₽, вычитается из первого этапаВосстановление из копии проверяется учением, а не наличием файловИсходный код и настройки в вашем репозитории с первого коммита

С чем приходят

Когда сервис держится на одном сервере и одном человеке

Одна машина — одна точка отказа

Приложение, база и файлы на одном сервере. Отказ диска или обновление системы означают простой неизвестной длины.

Копии есть, восстанавливать не пробовали

Задание копирования каждую ночь пишет «успешно», но никто не проверял, что из файлов получится рабочая база и сколько времени это займёт.

Внешняя система тянет за собой всё

Платёжный провайдер или 1С отвечают медленно, потоки приложения ждут, очередь запросов растёт, и страницы, не связанные с платежами, перестают открываться.

Выкладка роняет сервис, а вернуть нельзя

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

Перечень отказов

Шесть отказов, которые нужно обсудить до выбора схемы

Резервирование строится против конкретных отказов, а не вообще.

Отказ
Как проявляется
Чем закрываем
Что остаётся риском
ОтказПадение процессаошибка в коде, нехватка памяти
Как проявляетсяСервис не отвечает до перезапуска
Чем закрываемАвтоматический перезапуск, несколько копий приложения за балансировщиком, проверка готовности
Что остаётся рискомОшибка, которая повторяется на каждом запросе: перезапуск не лечит
ОтказОтказ серверапитание, железо, перегрев
Как проявляетсяВсе сервисы на узле недоступны сразу
Чем закрываемПриложение на двух и более узлах, состояние хранится не на узле, а в базе или общем хранилище
Что остаётся рискомУзлы стоят в одной стойке или на одном питании: отказ общий
ОтказСбой базы данныхузел или процесс базы
Как проявляетсяСервис жив, но операции не проходят
Чем закрываемРеплика с проверенным переключением, понятный порядок решения, кто главный
Что остаётся рискомПотеря последних записей при асинхронной репликации
ОтказОтказ внешней системыпровайдер, 1С, почта
Как проявляетсяМедленные ответы и ошибки на стыке
Чем закрываемТаймауты, ограниченные повторы, предохранитель, очередь и режим с урезанными функциями
Что остаётся рискомФункции, которые невозможны без этой системы, останутся недоступными
ОтказНеудачная выкладкаошибка или несовместимость
Как проявляетсяСервис падает после обновления
Чем закрываемВыкладка по частям, совместимость структуры данных со старой версией, откат одной командой
Что остаётся рискомНеобратимые изменения данных, которые версия успела записать
ОтказОшибка человекаудалили, перезаписали, ошиблись в настройке
Как проявляетсяДанные испорчены на всех репликах сразу
Чем закрываемКопии с возвратом на момент времени, ограничения прав на опасные операции, журнал действий
Что остаётся рискомОшибку замечают через дни, и копий нужной глубины уже нет
Цели

Сколько можно потерять и как долго можно ждать: две цифры, с которых начинается проект

Без этих значений нельзя ответить, достаточно ли надёжно. Их называет бизнес, а не разработчик.

Для каждого сервиса, а лучше для каждой его части, записываются два показателя.

  • Допустимая потеря данных (RPO): за какой период последние изменения можно потерять при аварии. Для ленты новостей это может быть час, для оплаченных заказов — ноль.
  • Допустимое время восстановления (RTO): сколько сервис может быть недоступен до возвращения. Для внутреннего справочника это рабочий день, для сервиса приёма платежей — минуты.

Эти показатели определяют схему. Нулевая потеря данных требует синхронной записи на вторую копию, что замедляет операции и усложняет эксплуатацию. Время восстановления в минуты требует автоматического переключения и людей, которые знают, как оно работает. Каждый шаг вниз по обоим показателям стоит заметно дороже предыдущего, поэтому на обследовании мы просим назвать не «как можно меньше», а цену простоя: сколько заказов и платежей не пройдёт за час.

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

Цель по доступности в процентах («три девятки») — следствие этих решений, а не их замена. Как читать такую цель и что считать простоем, описано в статье о доступности «три девятки».

Ступени резервирования

Четыре уровня защиты: что каждый переживает и что требует от команды

Выбор уровня — это выбор цены простоя. Начинать с высшего уровня почти никогда не нужно.

Уровень
Что переживает
Чего не переживает
Что требует от команды
УровеньКопии и проверенное восстановлениеминимум для любого сервиса
Что переживаетПотерю сервера, ошибку человека, порчу данных, если копии нужной глубины
Чего не переживаетОтказ, пока идёт восстановление: простой равен времени развёртывания и загрузки данных
Что требует от командыРегулярные проверки: раз в квартал копию разворачивают на чистом сервере и сверяют данные
УровеньГорячая реплика базы и запасной узел приложениярезерв с ручным переключением
Что переживаетОтказ узла, диска, базы с переключением вручную за минуты
Чего не переживаетОшибку в данных, которая попала на реплику; отказ площадки
Что требует от командыОписанный порядок переключения и человека, который выполнит его в рабочее время
УровеньНесколько узлов и автоматическое переключениерабочий режим при отказе узла
Что переживаетОтказ узла и базы без участия человека
Чего не переживаетОтказ всей площадки; ошибки конфигурации, которые копируются на все узлы
Что требует от командыМониторинг самого механизма переключения и учения; без них схема даёт ложное чувство надёжности
УровеньДве площадкиотказ всего помещения
Что переживаетОтказ узла, базы и площадки
Чего не переживаетОшибку человека на обеих площадках, если нет копий с возвратом на момент времени
Что требует от командыДвойное оборудование, канал между площадками, регулярные переключения; цена заметно выше
База данных

База данных: самая трудная часть отказоустойчивости

Приложение без состояния копируется просто, с данными сложнее.

Репликация: что именно копируется и когда

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

Переключение: кто решает, что главный упал

Опасный случай — когда оба узла считают себя главными и принимают записи: данные расходятся, и сводить их приходится вручную. Поэтому автоматическое переключение строится на внешнем арбитре (узлы голосуют), а не на правиле «не отвечает, значит, упал». Для PostgreSQL есть зрелые инструменты вроде Patroni; нужны ли они вам или хватит ручного переключения, решает размер системы и умение команды её сопровождать.

Репликация не заменяет копии

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

Восстановление проверяется, иначе его нет

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

Внешние системы

Как не дать чужому сбою стать своим

Таймаут на каждый вызов

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

Повторы с границей

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

Предохранитель

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

Очередь вместо ожидания

Что можно сделать позже (письмо, выгрузка в 1С), кладётся в очередь с повторной отправкой и не пропадёт, если система вернётся через час.

Выкладки

Выкладка и откат: заметная часть простоев вызвана нами самими

Обновления нередко вызывают простоев не меньше, чем железо, поэтому надёжность включает процесс выкладки.

  • Изменения структуры данных идут в два шага. Сначала добавляем новое так, чтобы старая версия приложения продолжала работать, потом переключаем код, и только после этого удаляем старое. Тогда откат кода возможен в любой момент.
  • Выкладка по частям. Новая версия сначала получает один узел или малую долю запросов; если ошибок становится больше, выкладка останавливается.
  • Откат отработан заранее. Предыдущая версия хранится собранной, порядок возврата проверен. Откат, который делают в первый раз во время аварии, обычно не получается.

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

Что делаем

Из чего состоит работа и сколько она стоит

Цены совпадают со страницей «Тарифы». Точная цена называется только у обследования, остановиться можно после любой ступени.

Обследование: один сервис

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

200 000 ₽ · 2–3 недели

Обследование: несколько систем

Сервис с базой, очередями, 1С и внешними обменами: зависимости и порядок запуска после аварии.

350 000 ₽ · 3–4 недели

Пилот, лёгкий: копии и восстановление

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

150 000–400 000 ₽ · 2–8 недель

Пилот, тяжёлый: реплика и переключение

Реплика базы, переключение, таймауты и предохранители на внешних вызовах, безопасная выкладка с откатом, учения с отключением узлов.

400 000–1 200 000 ₽ · 2–3 месяца

Вывод в эксплуатацию

Схема на все части сервиса, регламент учений, передача команде.

от 1 500 000 ₽ этапами по 300 000–700 000 ₽ · от 3 месяцев

Сопровождение

Плановые проверки восстановления, разбор инцидентов, пересмотр схемы. Сверх пакета — 5 000 ₽ в час.

20 000 / 60 000 / 120 000 ₽ в месяц
Процесс

Как идёт работа

2–4 недели — Обследование: отказы, цели, копии, уровень защиты

Выписываем одиночные точки отказа, спрашиваем цену простоя, берём последнюю копию и разворачиваем её. Для каждой части выбираем уровень защиты и записываем принятые риски.

От 3 недель — Построение

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

1–2 недели — Учения

Нарочно отключаем узел, базу, внешнюю систему, ломаем выкладку. Замеряем время восстановления и сравниваем с целью.

Перед передачей — Регламент

Что делать при каждом из шести отказов, кто решает о переключении, как запустить сервис после полной остановки.

Дальше — передача или сопровождение

Проверки делает ваша команда или сопровождение; схема пересматривается при росте нагрузки.

Цена

Что двигает цену внутри вилки

Цели по данным и времени

Нулевая потеря и минуты на восстановление стоят заметно больше, чем потеря за час и восстановление за смену.

Состояние сервиса

Если приложение хранит сессии и файлы на локальном диске, сначала его нужно сделать независимым от узла.

Число внешних зависимостей

У каждой системы свои сбои и своя безопасность повторов. Одни операции можно повторять, другие нельзя.

Требования контура

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

Контроль

Что остаётся у вас и чего мы не делаем

Остаётся у вас

  • Исходный код, конфигурации, сценарии развёртывания и восстановления в вашем репозитории с первого коммита.
  • Серверы, базы и копии на вашей стороне; схема воспроизводится по инструкции.
  • Цели, перечень принятых рисков, журнал учений.
  • Регламент по каждому из отказов с ответственными и порядком запуска после остановки.
  • Право остановиться после любой ступени: сделанное остаётся у вас по акту.

Мы этого не делаем

  • Не обещаем отсутствие простоев и не берём обязательств по доступности: она зависит от схемы, оборудования и вашей эксплуатации.
  • Не дежурим круглосуточно: автоматическое переключение уменьшает потребность в ночных вызовах, но не заменяет дежурную смену.
  • Не размещаем сервис у себя и не поставляем оборудование: серверы, площадки и каналы выбираете вы или ваш хостер.
  • Не защищаем от DDoS-атак и не оказываем услуги WAF, SIEM и IDS.
  • Не проводим аттестацию, лицензии ФСТЭК у нас нет. Работы дешевле 150 000 ₽ не берём.
Граница

Отказоустойчивость, высокая нагрузка и сопровождение: где проходит граница

Отказоустойчивость отвечает на вопрос «что будет, если что-то сломается». Высокая нагрузка отвечает на другой: «что будет, если придёт много пользователей». Решения частично общие, например несколько копий приложения, но цели разные: от нагрузки спасают кэш, очереди и отключение функций на пике, и они разобраны на странице высоконагруженного B2C-сервиса.

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

Порядок шагов по возрастанию цены собран в статье «Как сделать веб-сервис отказоустойчивым по шагам».

Инструменты

На чём собираем

Данные и копии
  • PostgreSQL: потоковая репликация, непрерывное архивирование журнала, возврат на момент времени
  • pgBackRest или аналогичный инструмент копий; хранение копий вне основного сервера
  • Patroni и совместимые средства автоматического переключения, если оно нужно
  • S3-совместимое хранилище для файлов, у вас или у выбранного вами хостера
Приложение и выкладка
  • Docker, Nginx или HAProxy, проверки готовности
  • RabbitMQ или очередь в PostgreSQL для отложенных задач
  • GitLab CI: сборка, выкладка по частям, откат
  • Метрики и оповещения в вашем контуре
Материалы

Материалы по теме

Статья

Как сделать веб-сервис отказоустойчивым по шагам

Порядок работ от дешёвого шага к дорогому: что даёт каждый и когда остановиться.

  • Одиночные точки отказа
  • Копии и проверка
  • Откат выкладки
Читать →
Статья

Что означает доступность «три девятки» и как её проверять

Как переводить цель по доступности в допустимый простой и что считать недоступностью.

  • Допустимый простой
  • SLI, SLO, SLA
  • Что проверить в договоре
Читать →
Статья

Как подготовить B2C-сервис к высокой нагрузке

Что делать, когда причина сбоя не отказ, а наплыв пользователей.

  • Оценка пика
  • Критический путь
  • Деградация вместо падения
Читать →
Заявка

Разберём, какие сбои ваш сервис сегодня не переживёт

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

Спасибо, заявка отправлена. Ответим в течение рабочего дня.

Не удалось отправить. Напишите в телеграм или позвоните.

Вопросы

Частые вопросы: разработка отказоустойчивого веб-сервиса

Сколько стоит разработка отказоустойчивого веб-сервиса?

Обследование стоит 200 000 ₽ за один сервис и 350 000 ₽ за несколько систем. Лёгкий пилот (копии, проверенное восстановление, резервный узел) — 150 000–400 000 ₽ за 2–8 недель, тяжёлый (реплика и переключение, защита внешних вызовов, откат выкладок) — 400 000–1 200 000 ₽ за 2–3 месяца. Схема с несколькими узлами и автоматическим переключением на всём продукте идёт этапами от 1 500 000 ₽.

С чего начать, если у нас один сервер?

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

Достаточно ли реплики базы вместо резервных копий?

Нет. Реплика защищает от отказа узла, но получает и ошибки: удалённая таблица исчезнет на ней сразу. От ошибок человека защищают копии с возвратом на момент времени. Нужны оба механизма.

Можно ли гарантировать «три девятки» или выше?

Мы не берём обязательств по доступности: она зависит от оборудования, площадки, вашей эксплуатации и внешних систем. Мы строим схему под ваши цели по потере данных и времени восстановления и измеряем результат на учениях.

Как проверяется, что восстановление работает?

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

Вы будете дежурить при авариях?

Круглосуточного дежурства у нас нет. Разбор инцидентов в рабочее время берёт сопровождение: 20 000, 60 000 или 120 000 ₽ в месяц, до 4, 12 или 25 часов, сверх пакета 5 000 ₽ в час. Для ночной реакции нужна ваша дежурная служба.

Кому принадлежат схема, скрипты и инструкции?

Вам. Исходный код, конфигурации, сценарии развёртывания и восстановления и регламенты лежат в вашем репозитории с первого коммита. Результат передаётся по акту, порядок передачи прав записан в договоре. Открытые компоненты остаются под своими лицензиями, их список входит в документацию.

Вы работаете только в Ростове-на-Дону?

Мы в Ростове-на-Дону, работаем с заказчиками по всей России: удалённо и в вашем контуре. Доступ к системам и обследование согласуем на старте с вашей службой безопасности.