← Назад к вопросам
Zero-downtime deployment для stateful приложения
3.0 Senior🔥 231 комментариев
#CI/CD и автоматизация
Условие
Опишите стратегию деплоя без простоя для приложения с базой данных:
Контекст
- Монолитное приложение на Java/Python
- PostgreSQL база данных
- Требуются миграции схемы БД при обновлении
- Нельзя терять запросы во время деплоя
Задачи
- Опишите процесс деплоя пошагово
- Как выполнять миграции БД без блокировки?
- Как обеспечить совместимость старой и новой версии?
- Как откатиться, если новая версия сломалась?
Требования
- Rolling update с health checks
- Graceful shutdown (завершение текущих запросов)
- Database migration без downtime
- Feature flags для постепенного включения функций
Вопросы
- Что такое backward-compatible миграции?
- Как тестировать процесс деплоя?
- Какие метрики мониторить во время деплоя?
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Zero-downtime deployment для stateful приложения
Пошаговый процесс деплоя
1. Подготовка (Pre-deployment)
# Создать снапшот БД перед деплоем
pg_dump -Fc production_db > backup_$(date +%Y%m%d_%H%M%S).dump
# Проверить backward-compatible миграции
python manage.py migrate --check
- Прогнать миграции на staging-копии production БД
- Подготовить feature flags для новых функций (выключены)
- Убедиться, что новая версия совместима со старой схемой БД
2. Database Migration (без блокировки)
-- ПРАВИЛЬНО: backward-compatible миграция
-- Шаг 1: Добавить колонку (не блокирует)
ALTER TABLE users ADD COLUMN email_verified boolean DEFAULT false;
-- Шаг 2: Заполнить данные (в фоне)
UPDATE users SET email_verified = true
WHERE email IS NOT NULL;
-- НЕПРАВИЛЬНО: блокирующая миграция
-- ALTER TABLE users RENAME COLUMN name TO full_name; -- ЛОМАЕТ старую версию!
Правила backward-compatible миграций:
- Добавлять колонки с DEFAULT — безопасно
- Удалять колонки — только после полного переключения на новую версию
- Переименовывать — через двухфазную миграцию (добавить новую → скопировать → удалить старую)
- CREATE INDEX CONCURRENTLY — не блокирует таблицу
3. Rolling Update с Health Checks
# Kubernetes Deployment
apiVersion: apps/v1
kind: Deployment
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0 # Ни один pod не убиваем
maxSurge: 1 # Поднимаем 1 новый перед удалением старого
template:
spec:
terminationGracePeriodSeconds: 60
containers:
- name: app
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 5"]
4. Graceful Shutdown
import signal
import sys
def graceful_shutdown(signum, frame):
# 1. Перестать принимать новые запросы
server.stop_accepting()
# 2. Дождаться завершения текущих запросов (timeout 30s)
server.wait_for_pending(timeout=30)
# 3. Закрыть соединения с БД
db.close()
sys.exit(0)
signal.signal(signal.SIGTERM, graceful_shutdown)
5. Feature Flags
if feature_flags.is_enabled('new_payment_flow', user=current_user):
return new_payment_handler(request)
else:
return old_payment_handler(request)
Постепенное включение: 1% → 5% → 25% → 50% → 100%.
Откат при сбое
# Быстрый откат через Kubernetes
kubectl rollout undo deployment/myapp
# Откат миграции (если backward-compatible)
python manage.py migrate myapp 0042 # предыдущая версия
Метрики мониторинга во время деплоя
- Error Rate (5xx) — должен оставаться < 0.1%
- Latency P95/P99 — не должна расти
- Active connections — плавный переход
- DB connection pool — не исчерпан
- Memory/CPU — в норме
Тестирование процесса деплоя
- Staging environment — идентичная production среда
- Canary deployment — новая версия на 5% трафика
- Chaos Engineering — убить pod во время миграции
- Load testing — k6/Locust во время деплоя