Стратегии деплоя без простоя
Развёртывание без простоя (zero-downtime deployment) — практика выпуска новых версий приложения без какого-либо прерывания работы для конечных пользователей. В мире, где даже секунды простоя означают потерю дохода, ущерб репутации и нарушение SLA, владение техниками деплоя без простоя необходимо для любого продакшен-сервиса.
Почему при деплое возникает простой
Традиционное развёртывание вызывает простой, потому что приложение нужно остановить для замены кода и перезапустить для загрузки новой версии. В этот период входящие запросы терпят неудачу. Типичные причины:
- Остановка старой версии до готовности новой
- Миграции базы данных с блокировкой таблиц
- Изменения конфигурации, требующие перезапуска
- Обновления зависимостей с нарушением совместимости
- Время холодного старта нового экземпляра
Blue-Green Deployment
Blue-green развёртывание поддерживает два идентичных продакшен-окружения. В любой момент одно (blue) обслуживает трафик, а другое (green) простаивает или обновляется. После деплоя и проверки новой версии на green трафик переключается с blue на green.
# Концептуальный процесс
1. Blue-окружение обслуживает продакшен-трафик
2. Деплой новой версии на Green
3. Запуск smoke-тестов на Green
4. Переключение балансировщика Blue → Green
5. Green теперь обслуживает продакшен
6. Blue становится окружением для отката
# Переключение в Nginx (упрощённо)
upstream app {
# До переключения:
# server blue.internal:8080;
# После переключения:
server green.internal:8080;
}
Преимущества: Мгновенный откат переключением обратно на blue. Полная валидация окружения до переключения трафика. Нет трафика со смешанными версиями.
Недостатки: Требует двойной инфраструктуры. Изменения схемы БД должны быть обратно совместимы.
Rolling Deployment
Rolling-развёртывание постепенно заменяет экземпляры старой версии новой, по одному (или несколько) за раз. В процессе обе версии могут одновременно обслуживать трафик.
# Kubernetes rolling update
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 4
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
template:
spec:
containers:
- name: app
image: myapp:v2.0
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
Преимущества: Не нужна двойная инфраструктура. Постепенный выкат снижает радиус поражения. Нативно работает с оркестраторами контейнеров.
Недостатки: Обе версии работают одновременно — нужна обратная совместимость. Откат медленнее. Управление сессиями между версиями требует внимания.
Canary Deployment
Canary-развёртывание направляет малый процент трафика на новую версию, пока основная часть продолжает идти на старую. Если метрики в норме, процент постепенно увеличивается до 100%.
# Nginx canary со взвешенным upstream
upstream app {
server old-version.internal:8080 weight=90;
server new-version.internal:8080 weight=10; # 10% canary
}
# Этапы постепенного выката:
# Этап 1: 5% на canary → мониторинг 15 минут
# Этап 2: 25% на canary → мониторинг 30 минут
# Этап 3: 50% на canary → мониторинг 30 минут
# Этап 4: 100% на canary → деплой завершён
Преимущества: Минимальный риск — только малая часть пользователей видит новую версию. Валидация реальным продакшен-трафиком. Проблемы обнаруживаются до полного выката.
Недостатки: Требует инфраструктуры для разделения трафика. мониторинг сайтов должен быть достаточно гранулярным. Более длительное время полного деплоя.
Стратегии миграции базы данных
Изменения схемы БД — самая сложная часть деплоя без простоя. Миграция, блокирующая таблицу или удаляющая столбец, сломает работающее приложение. Решение — паттерн expand-and-contract:
Фаза расширения (Expand)
Добавляем новые столбцы, таблицы или индексы без удаления существующих. Старая версия продолжает работать, потому что ничего из того, от чего она зависит, не изменилось.
-- Шаг 1: Добавить новый столбец (nullable, мгновенно в MySQL 8+)
ALTER TABLE users ADD COLUMN email_verified TINYINT(1) DEFAULT 0;
-- Шаг 2: Деплой версии, пишущей в оба столбца
-- Шаг 3: Заполнить существующие данные
UPDATE users SET email_verified = 1 WHERE verified_at IS NOT NULL;
Фаза сжатия (Contract)
После стабилизации новой версии и миграции данных удаляем старые столбцы или таблицы отдельным деплоем.
-- Шаг 4: Деплой версии, читающей только из нового столбца
-- Шаг 5: Удаление старого столбца (отдельная миграция)
ALTER TABLE users DROP COLUMN verified_at;
Корректное завершение (Graceful Shutdown)
Приложения должны корректно обрабатывать текущие запросы при завершении:
1. Получение сигнала SIGTERM
2. Прекращение приёма новых соединений
3. Завершение всех текущих запросов (с таймаутом)
4. Закрытие соединений с БД и другими ресурсами
5. Выход с кодом 0
# PHP-FPM graceful shutdown
process_control_timeout = 30
# Nginx graceful shutdown
nginx -s quit # Ожидает завершения активных соединений
Health Checks и готовность
Проверки здоровья — связующее звено деплоя без простоя. Балансировщик должен знать, когда новый экземпляр готов принимать трафик и когда старый должен перестать его получать.
// PHP health check эндпоинт
$checks = [
'database' => checkDatabaseConnection(),
'redis' => checkRedisConnection(),
'disk' => disk_free_space('/') > 100 * 1024 * 1024,
];
$healthy = !in_array(false, $checks, true);
http_response_code($healthy ? 200 : 503);
echo json_encode(['status' => $healthy ? 'ok' : 'unhealthy', 'checks' => $checks]);
Чеклист деплоя
- Миграции БД обратно совместимы (expand-and-contract)
- Приложение поддерживает graceful shutdown (обрабатывает SIGTERM)
- Health check эндпоинты реализованы и протестированы
- Балансировщик проверяет здоровье перед маршрутизацией
- План отката документирован и протестирован
- Feature flags используются для рискованных изменений
- Настроены алерты на error rate, задержку и доступность
- Статические ресурсы версионированы (cache busting)
- Хранилище сессий вынесено (Redis, БД)
Мониторинг во время деплоя
| Метрика | Нормальный диапазон | Порог алерта |
|---|---|---|
| Частота ошибок (5xx) | < 0.1% | > 1% |
| P95 задержка | < 500 мс | > 2x от базового уровня |
| Частота запросов | Стабильная | Падение > 20% |
| Использование CPU | < 70% | > 90% |
| Использование памяти | < 80% | > 95% |
| Активные соединения | Стабильно | Резкий скачок или падение |
Итоги
Деплой без простоя достижим с любым стеком через комбинацию стратегий: blue-green для мгновенного переключения, rolling для постепенной замены и canary для валидации с минимальным риском. Ключи к успеху — обратно совместимые миграции БД, корректное завершение работы, надёжные проверки здоровья и комплексный мониторинг. Начните с простейшей стратегии, удовлетворяющей вашим потребностям, и развивайте по мере роста приложения и команды.
Проверьте ваш сайт прямо сейчас
Проверить →