Содержание
Релиз без простоя получается, когда новая версия запускается рядом со старой, трафик переключается только после проверки, а база данных меняется совместимыми шагами. Для этого используют три подхода: blue-green — переключение между двумя окружениями, canary — постепенный перевод части пользователей и feature flags — выпуск кода выключенным с включением функции отдельно. Небольшому продукту обычно хватает последовательной замены экземпляров и флагов.
Разберём, как работает каждый подход и как не сломать базу данных при выкладке.
Почему релизы вызывают простой?
Релизы вызывают простой, когда приложение останавливают перед запуском новой версии, когда новая версия несовместима с текущей схемой базы или когда ошибку обнаруживают уже на всех пользователях. Каждая из этих причин устраняется по-своему.
Типичные источники простоя:
- остановка единственного экземпляра приложения на время обновления;
- миграция базы, которая блокирует таблицу или ломает старый код;
- очистка кешей и прогрев, во время которых сайт работает медленно;
- ошибка в новой версии, которую приходится откатывать под нагрузкой;
- фоновые задачи, которые старые воркеры не могут обработать после смены формата.
Чем отличаются blue-green, canary и feature flags?
Blue-green, canary и feature flags по-разному снижают риск: первый позволяет мгновенно переключиться и откатиться, второй ограничивает число пользователей, которых затронет ошибка, третий отделяет выкладку кода от включения функции.
| Подход | Как работает | Плюсы | Что требует |
|---|---|---|---|
| Последовательная замена | Экземпляры обновляются по одному | Просто, встроено в оркестраторы | Несколько экземпляров, совместимость версий |
| Blue-green | Два окружения, трафик переключается целиком | Мгновенный откат | Двойные ресурсы на время релиза |
| Canary | Новая версия сначала на небольшой доле трафика | Ошибка затрагивает немногих | Маршрутизация трафика и метрики |
| Feature flags | Код выкладывается выключенным, функция включается отдельно | Включение и отключение без релиза | Дисциплина удаления старых флагов |
Фото: Unsplash
Как менять базу данных без простоя?
Базу данных меняют без простоя по схеме «расширить — перенести — сузить»: сначала добавляют новое, совместимое со старым кодом, затем переключают код, и только после этого удаляют старое. Так в любой момент и старая, и новая версии приложения работают с одной и той же схемой.
Пример: переименование столбца phone в phone_number.
Релиз 1 — расширение
добавить столбец phone_number (nullable)
код пишет в оба столбца, читает из phone
фоновая задача копирует старые значения
Релиз 2 — переключение
код читает и пишет phone_number
Релиз 3 — сужение
удалить столбец phone
Правила безопасных миграций
- Не удалять и не переименовывать столбцы в том же релизе, где меняется код.
- Новые столбцы добавлять допускающими пустые значения или со значением по умолчанию.
- Индексы на больших таблицах создавать без блокировки записи — о том, как, в статье индексы в PostgreSQL.
- Большие переносы данных выполнять фоновыми задачами частями.
- Проверять миграции на копии продакшен-объёма данных.
Как использовать feature flags?
Feature flags позволяют выкладывать незаконченную или рискованную функцию выключенной и включать её отдельно — сначала для команды, затем для части пользователей, затем для всех. Если что-то идёт не так, функция выключается за секунды без нового релиза.
if (Feature::active('new-checkout', $user)) {
return $this->newCheckout($cart);
}
return $this->legacyCheckout($cart);
Что важно:
- включать функцию постепенно и следить за метриками и ошибками;
- удалять флаг и старую ветку кода после полного включения — иначе код обрастает условиями;
- не использовать флаги как замену правам доступа и настройкам.
С чего начать небольшой команде?
Небольшой команде стоит начать с автоматической выкладки, нескольких экземпляров приложения с последовательной заменой, проверки состояния перед приёмом трафика и совместимых миграций. Blue-green и canary добавляют, когда цена ошибки и нагрузка это оправдывают.
План:
- автоматизировать выкладку в конвейере — подробнее в статье CI/CD на GitHub Actions;
- запускать не меньше двух экземпляров приложения и заменять их по одному;
- добавить эндпоинт проверки готовности — балансировщик не шлёт трафик на неготовый экземпляр;
- писать миграции по схеме «расширить — перенести — сузить»;
- подготовить быстрый откат и проверять его.
Коротко
- Простой при релизе вызывают остановка приложения, несовместимые миграции и ошибки на всех пользователях.
- Последовательная замена — база; blue-green даёт мгновенный откат, canary ограничивает охват ошибки.
- Feature flags отделяют выкладку кода от включения функции.
- Меняйте базу по схеме «расширить — перенести — сузить», а не одним шагом.
- Начните с автоматической выкладки, двух экземпляров, проверки готовности и совместимых миграций.
Частые вопросы
Нужен ли Kubernetes для релизов без простоя?
Нет. Последовательную замену можно сделать и на обычных серверах за балансировщиком, и в управляемых контейнерных сервисах. Kubernetes упрощает это, но не обязателен.
Как откатить релиз с миграцией базы?
Если миграция совместима с предыдущей версией кода, достаточно вернуть старую версию приложения — схема подходит обеим. Поэтому разрушительные изменения схемы выносят в отдельный поздний релиз.
Сколько feature flags можно держать одновременно?
Столько, сколько команда успевает отслеживать. Каждый флаг должен иметь владельца и срок удаления, иначе код обрастает условиями, которые никто не решается убрать.



