← Назад к вопросам

Какие типы деплоймента знаешь?

2.0 Middle🔥 201 комментариев
#DevOps и инфраструктура

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Типы развёртывания (Deployment Strategies) приложений

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

1. Big Bang / Переключение (All-at-Once Deployment)

Одновременное обновление всех серверов с новой версией. Самый простой и старый способ.

# Простейшая схема
# 1. Остановить приложение
sudo systemctl stop myapp

# 2. Заменить файлы
cp -r /new/version/* /app/

# 3. Запустить новую версию
sudo systemctl start myapp

# Результат: 0 → 100% новая версия мгновенно
# Время простоя: зависит от времени выключения/загрузки

Преимущества:

  • Очень просто реализовать
  • Всё одновременно, нет двойной нагрузки

Недостатки:

  • Время простоя (downtime)
  • Если что-то сломалось — откатывать сложнее
  • Нет способа быстро вернуться

Когда использовать:

  • Развитие (development)
  • Критичные исправления багов (если downtime приемлем)

2. Постепенное развёртывание (Rolling Deployment)

Обновление серверов по одному или партиями, сохраняя обслуживание трафика на оставшихся.

# Процесс:
# Шаг 1: Server1 (v1) + Server2 (v1) + Server3 (v1) → Load Balancer
#
# Шаг 2: обновляем Server1
#        Server1 (v2) + Server2 (v1) + Server3 (v1) → Load Balancer
#
# Шаг 3: обновляем Server2
#        Server1 (v2) + Server2 (v2) + Server3 (v1) → Load Balancer
#
# Шаг 4: обновляем Server3
#        Server1 (v2) + Server2 (v2) + Server3 (v2) → Load Balancer

# Kubernetes пример
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1        # Максимум 1 дополнительный pod
      maxUnavailable: 1  # Максимум 1 недоступный pod
  template:
    # ... pod spec

Преимущества:

  • Нет полного downtime
  • Легко откатывать — просто остановить процесс
  • Мониторишь проблемы во время развёртывания

Недостатки:

  • Требует больше времени
  • Требует load balancer
  • В промежутке две версии работают одновременно
  • Могут быть проблемы с несовместимостью версий БД

Когда использовать:

  • Production с требованием без downtime
  • Когда нет срочности
  • Для большинства web приложений

3. Blue-Green развёртывание

Две полностью идентичные среды: одна работает (Blue), вторая получает обновление (Green). Затем переключаемся.

# Структура:
# Blue Environment:  Server1, Server2, Server3 (v1) ← Production traffic
# Green Environment: Server4, Server5, Server6 (подготавливается v2)

# Процесс:
# 1. Развернуть v2 в Green
# 2. Протестировать Green
# 3. Переключить Load Balancer с Blue на Green
# 4. Blue остаётся готовым для быстрого отката

# Nginx конфигурация
upstream blue_backend {
    server server1:8000;
    server server2:8000;
    server server3:8000;
}

upstream green_backend {
    server server4:8000;
    server server5:8000;
    server server6:8000;
}

server {
    listen 80;
    
    # Текущее направление трафика
    set $backend "blue_backend";
    
    location / {
        proxy_pass http://$backend;
    }
}

# Для переключения просто меняем переменную
# set $backend "green_backend";

Преимущества:

  • Мгновенное переключение (zero downtime)
  • Легко откатывать — просто переключить обратно
  • Можно полностью протестировать новую версию
  • Обе версии работают параллельно

Недостатки:

  • Требует в два раза больше ресурсов
  • Дороговато для малых команд
  • Сложнее синхронизировать БД

Когда использовать:

  • Production критичные приложения
  • Когда откат должен быть мгновенным
  • Когда бюджет позволяет
# Python пример управления Blue-Green
import subprocess
from typing import Literal

class DeploymentManager:
    def __init__(self):
        self.current_active: Literal["blue", "green"] = "blue"
    
    def deploy_to_inactive(self, version: str) -> bool:
        """Развёртываем в неактивной среде"""
        inactive = "green" if self.current_active == "blue" else "blue"
        print(f"Развёртываю {version} в {inactive}...")
        
        # Развёртывание
        result = subprocess.run(
            ["./deploy.sh", inactive, version],
            capture_output=True
        )
        
        if result.returncode != 0:
            print(f"Ошибка развёртывания: {result.stderr}")
            return False
        
        # Тестирование
        if not self.test_environment(inactive):
            print(f"Тесты не прошли в {inactive}")
            return False
        
        print(f"Готово к переключению на {inactive}")
        return True
    
    def switch_traffic(self) -> bool:
        """Переключаем трафик на новую версию"""
        new_active = "green" if self.current_active == "blue" else "blue"
        print(f"Переключаю трафик на {new_active}...")
        
        # Обновляем конфигурацию load balancer
        result = subprocess.run(
            ["./switch_lb.sh", new_active],
            capture_output=True
        )
        
        if result.returncode == 0:
            self.current_active = new_active
            print(f"Успешно переключены на {new_active}")
            return True
        return False
    
    def rollback(self) -> bool:
        """Откат на предыдущую версию"""
        return self.switch_traffic()  # Просто переключаемся обратно
    
    def test_environment(self, env: str) -> bool:
        """Тестируем окружение перед переключением"""
        # Smoke tests
        pass

4. Canary развёртывание

Постепенное направление трафика на новую версию. Сначала 5%, потом 25%, потом 100%.

# Процесс:
# Этап 1: 95% трафика на v1, 5% на v2 (Canary)
# Этап 2: 75% трафика на v1, 25% на v2
# Этап 3: 50/50
# Этап 4: 100% на v2

# Если на любом этапе обнаружена проблема → откатываемся

# Kubernetes с Istio
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: myapp
spec:
  hosts:
  - myapp
  http:
  - match:
    - uri:
        prefix: /
    route:
    - destination:
        host: myapp
        subset: v1
      weight: 95  # 95% на v1
    - destination:
        host: myapp
        subset: v2
      weight: 5   # 5% на v2 (Canary)

Преимущества:

  • Минимальный риск — видишь проблемы на 5% трафика
  • Не требует двойных ресурсов
  • Мониторишь метрики в реальном времени

Недостатки:

  • Требует хорошей инфраструктуры мониторинга
  • Медленнее, чем Big Bang
  • Требует автоматизации переключения

Когда использовать:

  • Production с высокой надёжностью
  • Когда рисков больше, чем можно себе позволить
  • Machine Learning модели (A/B тестирование)

5. Shadow развёртывание

Новая версия получает копию трафика, но результаты не используются. Только для анализа.

# Процесс:
# Запрос → Load Balancer
#          ├→ Production (v1) → Ответ клиенту
#          └→ Shadow (v2) → Логируем результаты (не отправляем клиенту)

# Затем анализируем логи и сравниваем поведение

# nginx конфигурация
server {
    listen 80;
    
    location / {
        # Основной запрос
        proxy_pass http://production;
        
        # Shadow копия
        proxy_pass_request_headers off;
        proxy_pass_request_body off;
        
        # Отправляем в shadow с задержкой
        access_log /var/log/shadow.log shadow_format;
    }
}

Преимущества:

  • Нулевой риск для пользователей
  • Получаешь реальные данные о поведении
  • Можно тестировать с production трафиком

Недостатки:

  • Требует двойную обработку трафика
  • Медленнее (дополнительная нагрузка)
  • Нужно хорошее логирование для анализа

Когда использовать:

  • Перед Canary развёртыванием критичных изменений
  • Миграция между версиями БД
  • Machine Learning модели

6. Feature Flags / Toggling

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

# Пример с feature flags
from enum import Enum

class FeatureFlags(Enum):
    NEW_PAYMENT_SYSTEM = "new_payment_system"
    AI_RECOMMENDATIONS = "ai_recommendations"
    DARK_MODE = "dark_mode"

def process_payment(user_id: int, amount: float):
    if is_feature_enabled(user_id, FeatureFlags.NEW_PAYMENT_SYSTEM):
        # Используем новую систему (5% пользователей)
        return new_payment_system.process(user_id, amount)
    else:
        # Используем старую систему (95% пользователей)
        return old_payment_system.process(user_id, amount)

def is_feature_enabled(user_id: int, feature: FeatureFlags) -> bool:
    """Проверяем, включена ли функция для пользователя"""
    # Хранится в конфигурации или БД
    config = load_feature_config(feature)
    return user_id % 100 < config.percentage

Преимущества:

  • Разделяет develop и deploy
  • Можно быстро отключить проблемную функцию
  • Не нужно откатывать версию

Недостатки:

  • Код становится сложнее (много if/else)
  • Нужна система управления флагами

Когда использовать:

  • Вместе с Canary развёртыванием
  • Для постепенного включения функций

7. Serverless развёртывание

Отправляем код в AWS Lambda, Google Cloud Functions, и так далее.

# AWS Lambda функция
import json

def lambda_handler(event, context):
    """Точка входа для Lambda"""
    
    try:
        # Обработка запроса
        result = process_request(event)
        
        return {
            'statusCode': 200,
            'body': json.dumps(result)
        }
    except Exception as e:
        return {
            'statusCode': 500,
            'body': json.dumps({'error': str(e)})
        }

# Deploy с помощью Serverless Framework
# serverless deploy

# Автоматическое масштабирование, no downtime

Преимущества:

  • Автоматическое масштабирование
  • Платишь только за используемые ресурсы
  • Не нужно управлять серверами
  • Автоматический upgrade инфраструктуры

Недостатки:

  • Cold start проблемы
  • Зависимость от провайдера
  • Сложнее отлаживать
  • Не подходит для длительных операций

Когда использовать:

  • Microservices
  • Async задачи (webhook обработка)
  • Scheduled jobs

Сравнение стратегий

СтратегияDowntimeРесурсыСложностьОткатRiskЛучше для
Big BangВысокийНизкиеНизкаяМедленныйВысокийDev, тесты
RollingНизкийНормальныеСредняяБыстрыйСреднийProd
Blue-Green0ДвойныеСредняяМгновенныйНизкийКритичное
Canary0НормальныеВысокаяМгновенныйНизкийВысокая надёжность
Shadow0ДвойныеСредняяN/A0Тестирование
Feature Flags0НормальныеСредняяМгновенныйНизкийМикросервисы
Serverless0ПеременныеНизкаяМгновенныйНизкийAsync, масштабирование

Best Practices

Для production:

  1. Используй Rolling или Blue-Green для большинства случаев
  2. Canary для критичных изменений
  3. Shadow для миграций
  4. Всегда имей rollback план
  5. Хорошее мониторинг и логирование
  6. Автоматизируй процесс развёртывания
  7. Тестируй развёртывание в staging
# Современный pipeline
class DeploymentPipeline:
    def run(self, version: str):
        # 1. Build
        self.build_image(version)
        
        # 2. Test
        self.run_tests(version)
        
        # 3. Deploy to staging
        self.deploy_to_staging(version)
        self.run_smoke_tests()
        
        # 4. Canary deploy to production
        self.canary_deploy(version, percentage=5)
        time.sleep(300)  # Мониторим 5 минут
        
        # 5. Проверяем метрики
        if self.check_metrics_ok():
            # 6. Полное развёртывание
            self.full_deploy(version)
        else:
            # Откат
            self.rollback()