Цели модуля
После модуля студент сможет:
- Выбирать модель деплоя под задачу (Serverless, VDS, Kubernetes)
- Проектировать single binary стратегию для Go-сервисов
- Понимать различия между cron и timer triggers
- Реализовывать graceful shutdown для long-running процессов
- Применять стратегии rollout: canary, blue-green, rolling
- Использовать feature flags для безопасных релизов
- Понимать принципы GitOps
4.1 Модели деплоя: обзор
Три основные модели
| Модель | Описание | Когда использовать |
|---|---|---|
| Serverless | Функции по запросу | Нестабильная нагрузка, малый трафик |
| VDS | Виртуальный сервер | Простые сервисы, стабильная нагрузка |
| Kubernetes | Оркестрация контейнеров | Сложные системы, автоскейлинг |
Критерии выбора
-
Характер нагрузки
- Пиковая/нестабильная: Serverless
- Стабильная: VDS
- Растущая: Kubernetes
-
Операционные возможности команды
- Нет DevOps: Serverless или managed VDS
- Есть DevOps: Kubernetes
-
Стоимость
- Малый трафик: Serverless
- Средний трафик: VDS
- Большой трафик: Kubernetes
-
Требования к latency
- Критична: VDS или Kubernetes (нет cold start)
- Не критична: Serverless
-
Сложность сервиса
- Простой: Serverless
- Средний: VDS
- Сложный (много зависимостей): Kubernetes
Эволюция деплоя
Рекомендуемый путь:
Прототип -> Serverless -> VDS -> Kubernetes
Не начинайте с Kubernetes если нет реальной необходимости.
4.2 Serverless deployment model
Что такое Serverless
Serverless — модель где облачный провайдер управляет инфраструктурой. Код выполняется в функциях (FaaS) по запросу.
Примеры:
- AWS Lambda
- Yandex Cloud Functions
- Google Cloud Functions
- Azure Functions
Характеристики Serverless
- Оплата за выполнение (per invocation)
- Автоскейлинг от 0 до N
- Cold start (задержка при первом вызове)
- Ограничения по времени выполнения (обычно 15 минут)
- Stateless по умолчанию
- Managed инфраструктура
Архитектура Serverless сервиса
API Gateway
|
v
Cloud Function (api)
|
v
Cloud Function (git-gateway)
|
v
Timer Trigger (outbox-relay)
|
v
Timer Trigger (saga-orchestrator)
|
v
Timer Trigger (hmac-rotator)
Пример структуры для Yandex Cloud Functions
cmd/
├── api/main.go # REST API функция
├── git-gateway/main.go # Git Smart HTTP функция
├── outbox-relay/main.go # Outbox relay (timer trigger)
├── saga-orchestrator/main.go # Saga orchestrator (timer trigger)
└── hmac-rotator/main.go # HMAC rotator (timer trigger)
Terraform для Serverless
hclresource "yandex_function" "api" { name = "api-function" user_hash = data.archive_file.api.output_base64sha256 runtime = "golang123" entrypoint = "Handle" memory = "256" execution_timeout = "30" service_account_id = yandex_iam_service_account.function_sa.id environment = { DATABASE_DSN = var.database_dsn LOG_LEVEL = "info" } secrets { id = yandex_lockbox_secret_version.hmac_key.id version_id = yandex_lockbox_secret_version.hmac_key.version_id key = "hmac_key" environment_variable = "HMAC_KEY" } } resource "yandex_function_trigger" "outbox_relay" { name = "outbox-relay-trigger" function { id = yandex_function.outbox_relay.id } timer { cron_expression = "*/5 * * * *" } }
Плюсы Serverless
- Нет управления инфраструктурой
- Автоскейлинг от 0
- Оплата только за использование
- Быстрый старт
- Встроенная отказоустойчивость
Минусы Serverless
- Cold start (100ms-2s задержка)
- Ограничения по времени выполнения
- Сложность отладки
- Vendor lock-in
- Сложность для long-running процессов
- Ограничения по памяти/CPU
Когда использовать Serverless
- API с нестабильной нагрузкой
- Обработка событий (webhooks, очереди)
- Периодические задачи (cron)
- Прототипы и MVP
- Малый трафик
4.3 VDS deployment model
Что такое VDS
VDS (Virtual Dedicated Server) — виртуальный сервер с выделенными ресурсами. Полный контроль над окружением.
Характеристики VDS
- Фиксированная оплата (месяц/год)
- Полный контроль над ОС
- Long-running процессы
- Нет cold start
- Нужна настройка и поддержка
- Ручной или полуавтоматический скейлинг
Архитектура VDS сервиса
Nginx (reverse proxy)
|
v
git-server (HTTP server + workers)
|
├── HTTP server (api + git-gateway)
├── Outbox relay worker
├── Saga orchestrator worker
└── HMAC rotator worker
Пример структуры для VDS
cmd/
└── app/
├── main.go # Entry point
└── commands/
├── serve.go # HTTP server
├── worker.go # Background workers
├── migrate.go # Миграции
└── version.go
Systemd units
# /etc/systemd/system/git-server.service
[Unit]
Description=Git Server
After=network.target postgresql.service
[Service]
Type=simple
User=git-server
ExecStart=/usr/local/bin/git-server serve
Restart=always
RestartSec=5
LimitNOFILE=65536
Environment=APP_CONFIG_PATH=/etc/git-server/config.yaml
[Install]
WantedBy=multi-user.target
# /etc/systemd/system/git-server-worker.service
[Unit]
Description=Git Server Worker
After=network.target postgresql.service
[Service]
Type=simple
User=git-server
ExecStart=/usr/local/bin/git-server worker
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
Ansible playbook для деплоя
yaml- name: Deploy git-server hosts: staging become: yes tasks: - name: Create app user user: name: git-server system: yes shell: /usr/sbin/nologin - name: Copy binary copy: src: bin/git-server dest: /usr/local/bin/git-server mode: "0755" notify: restart git-server - name: Copy config template: src: templates/config.yaml.j2 dest: /etc/git-server/config.yaml mode: "0640" notify: restart git-server - name: Copy systemd units copy: src: systemd/git-server.service dest: /etc/systemd/system/ notify: - reload systemd - restart git-server - name: Enable and start service systemd: name: git-server enabled: yes state: started handlers: - name: reload systemd systemd: daemon_reload: yes - name: restart git-server systemd: name: git-server state: restarted
Плюсы VDS
- Полный контроль
- Нет cold start
- Long-running процессы
- Предсказуемая стоимость
- Простота для небольших сервисов
- Легко отлаживать
Минусы VDS
- Ручное управление инфраструктурой
- Нет автоскейлинга
- Нужно настраивать мониторинг
- Single point of failure (без дополнительных мер)
- Патчинг ОС и безопасности
Когда использовать VDS
- Стабильная нагрузка
- Простые сервисы
- Long-running процессы
- Ограниченный бюджет
- Команда без DevOps экспертизы
4.4 Kubernetes deployment model
Что такое Kubernetes
Kubernetes — оркестратор контейнеров. Автоматизирует деплой, скейлинг, управление контейнеризированными приложениями.
Характеристики Kubernetes
- Декларативная конфигурация
- Автоскейлинг (HPA, VPA)
- Self-healing (перезапуск подов)
- Service discovery
- Rolling updates
- Rich экосистема
Архитектура Kubernetes сервиса
Ingress
|
v
Service
|
v
Deployment (replicas: 3)
├── Pod 1 (git-server)
├── Pod 2 (git-server)
└── Pod 3 (git-server)
|
v
CronJob (outbox-relay)
CronJob (saga-orchestrator)
Пример Deployment
yamlapiVersion: apps/v1 kind: Deployment metadata: name: git-server spec: replicas: 3 selector: matchLabels: app: git-server template: metadata: labels: app: git-server spec: containers: - name: git-server image: registry.example.com/git-server:v1.0.0 ports: - containerPort: 8080 env: - name: APP_DATABASE_DSN valueFrom: secretKeyRef: name: git-server-secrets key: database-dsn resources: requests: memory: "256Mi" cpu: "250m" limits: memory: "512Mi" cpu: "500m" livenessProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 5 periodSeconds: 10 readinessProbe: httpGet: path: /readyz port: 8080 initialDelaySeconds: 5 periodSeconds: 5
Пример CronJob
yamlapiVersion: batch/v1 kind: CronJob metadata: name: outbox-relay spec: schedule: "*/5 * * * *" jobTemplate: spec: template: spec: containers: - name: outbox-relay image: registry.example.com/git-server:v1.0.0 command: ["/usr/local/bin/git-server", "worker", "--job=outbox-relay"] restartPolicy: OnFailure
Плюсы Kubernetes
- Автоскейлинг
- Self-healing
- Rolling updates без downtime
- Service discovery
- Rich экосистема (Helm, Istio, ArgoCD)
- Portability между облаками
Минусы Kubernetes
- Высокая операционная сложность
- Крутая кривая обучения
- Требует DevOps экспертизы
- Избыточен для простых сервисов
- Стоимость (control plane, мониторинг)
Когда использовать Kubernetes
- Много микросервисов
- Нужен автоскейлинг
- Есть DevOps команда
- Сложные требования к деплою
- Multi-cloud или hybrid
4.5 Single binary strategy
Что это
Весь сервис компилируется в один бинарник с subcommands.
bashgit-server serve # HTTP server git-server worker # Background workers git-server migrate # Миграции git-server fsck # DR check git-server version # Версия
Реализация с cobra
go// cmd/app/main.go package main import ( "github.com/spf13/cobra" ) func main() { rootCmd := &cobra.Command{ Use: "git-server", Short: "Git server application", } rootCmd.AddCommand( newServeCmd(), newWorkerCmd(), newMigrateCmd(), newFsckCmd(), newVersionCmd(), ) if err := rootCmd.Execute(); err != nil { os.Exit(1) } } // cmd/app/commands/serve.go func newServeCmd() *cobra.Command { return &cobra.Command{ Use: "serve", Short: "Start HTTP server", RunE: runServe, } } func runServe(cmd *cobra.Command, args []string) error { ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM) defer stop() cfg, err := config.Load() if err != nil { return fmt.Errorf("load config: %w", err) } app, err := app.Build(ctx, cfg) if err != nil { return fmt.Errorf("build app: %w", err) } defer app.Close() return runHTTPServer(ctx, app, cfg) }
Преимущества single binary
- Простота деплоя: один артефакт
- Версионирование: одна версия для всех компонентов
- Тестирование: один бинарник для всех сценариев
- Rollback: переключение на предыдущую версию
- Docker: один образ для всех ролей
Когда использовать
- Один сервис с несколькими ролями (HTTP + workers)
- Нужна простота деплоя
- Малая или средняя команда
Когда НЕ использовать
- Независимое масштабирование компонентов
- Разные команды владеют разными компонентами
- Разные требования к ресурсам
4.6 Cron vs timer triggers
Cron (VDS/Kubernetes)
Cron — планировщик задач по расписанию. Задачи выполняются периодически внутри процесса или через CronJob.
Примеры cron expressions:
* * * * * * # каждую секунду
0 * * * * * # каждую минуту
*/5 * * * * * # каждые 5 минут
0 0 * * * * # каждый час
0 0 0 * * * # каждый день в полночь
Timer triggers (Serverless)
Timer trigger — облачный сервис который вызывает функцию по расписанию.
hclresource "yandex_function_trigger" "outbox_relay" { timer { cron_expression = "*/5 * * * *" } }
Сравнение
| Критерий | Cron (VDS/K8s) | Timer Triggers (Serverless) |
|---|---|---|
| Где выполняется | В процессе / CronJob | Облачная функция |
| Cold start | Нет | Да |
| Состояние | Может быть | Stateless |
| Масштабирование | Ручное / HPA | Автоматическое |
| Стоимость | Фиксированная | Per invocation |
| Мониторинг | Self-hosted | Managed |
Когда что использовать
Cron (VDS/K8s):
- Long-running задачи
- Нужен доступ к состоянию
- Стабильная нагрузка
Timer triggers (Serverless):
- Короткие периодические задачи
- Нестабильная нагрузка
- Нет инфраструктуры
Реализация cron в Go (robfig/cron)
goimport "github.com/robfig/cron/v3" type Scheduler struct { cron *cron.Cron } func NewScheduler() *Scheduler { return &Scheduler{ cron: cron.New(cron.WithSeconds()), } } func (s *Scheduler) Register(name, schedule string, job func()) error { _, err := s.cron.AddFunc(schedule, func() { log.Info("job started", "job", name) job() log.Info("job completed", "job", name) }) return err } func (s *Scheduler) Start() { s.cron.Start() } func (s *Scheduler) Stop() { ctx := s.cron.Stop() <-ctx.Done() }
4.7 Graceful shutdown (углублённо)
Что такое graceful shutdown
При получении сигнала завершения (SIGINT, SIGTERM) сервис должен:
- Перестать принимать новые запросы
- Дождаться завершения текущих запросов
- Закрыть соединения с БД
- Освободить ресурсы
- Завершиться чисто
Почему это важно
Без graceful shutdown:
- Активные запросы обрываются
- Транзакции остаются открытыми
- События теряются
- Клиенты получают ошибки
Реализация для HTTP сервера
gofunc runHTTPServer(ctx context.Context, app *App, cfg *Config) error { srv := &http.Server{ Addr: cfg.HTTPAddr, Handler: app.Router, ReadTimeout: cfg.ReadTimeout, WriteTimeout: cfg.WriteTimeout, IdleTimeout: cfg.IdleTimeout, } // Запуск в горутине go func() { log.Info("server starting", "addr", cfg.HTTPAddr) if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { log.Error("server error", "error", err) } }() // Ждём сигнала <-ctx.Done() log.Info("shutdown signal received") // Graceful shutdown с таймаутом shutdownCtx, cancel := context.WithTimeout(context.Background(), cfg.ShutdownTimeout) defer cancel() if err := srv.Shutdown(shutdownCtx); err != nil { log.Error("graceful shutdown failed, forcing close", "error", err) return srv.Close() } log.Info("server stopped gracefully") return nil }
Graceful shutdown для workers
gofunc runWorker(ctx context.Context, app *App, cfg *Config) error { worker := app.Worker // Запуск в горутине go func() { log.Info("worker starting") worker.Run(ctx) }() // Ждём сигнала <-ctx.Done() log.Info("shutdown signal received") // Graceful shutdown с таймаутом shutdownCtx, cancel := context.WithTimeout(context.Background(), cfg.ShutdownTimeout) defer cancel() if err := worker.Shutdown(shutdownCtx); err != nil { log.Error("worker shutdown failed", "error", err) return err } log.Info("worker stopped gracefully") return nil }
Drain connections
При shutdown нужно дождаться завершения активных запросов:
gofunc (s *Server) Shutdown(ctx context.Context) error { // 1. Закрываем listener (не принимаем новые соединения) s.listener.Close() // 2. Ждём завершения активных запросов s.waitGroup.Wait() // 3. Закрываем idle соединения s.closeIdleConnections() return nil }
Systemd и graceful shutdown
Systemd по умолчанию отправляет SIGTERM и ждёт TimeoutStopSec.
[Service]
ExecStart=/usr/local/bin/git-server serve
KillSignal=SIGTERM
TimeoutStopSec=30
Если сервис не завершился за 30 секунд — SIGKILL.
Kubernetes и graceful shutdown
Kubernetes отправляет SIGTERM при удалении пода.
terminationGracePeriodSeconds: 30
PreStop hook для drain:
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 5"]
Это даёт time для service discovery обновления.
4.8 Стратегии rollout
Rolling update
Постепенная замена подов/инстансов.
Deployment:
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
Плюсы:
- Без downtime
- Простота
Минусы:
- Смешанные версии во время rollout
- Нет быстрого rollback
Blue-Green
Две идентичные среды: blue (текущая) и green (новая). Переключение трафика мгновенно.
Blue (v1.0) <- трафик
Green (v1.1) <- standby
Переключение:
Blue (v1.0) <- standby
Green (v1.1) <- трафик
Плюсы:
- Мгновенный rollback
- Нет смешанных версий
- Полное тестирование перед переключением
Минусы:
- Двойные ресурсы
- Сложность с stateful данными
Canary
Постепенное увеличение трафика на новую версию.
Шаг 1: 5% трафика на v1.1, 95% на v1.0
Шаг 2: 25% трафика на v1.1, 75% на v1.0
Шаг 3: 50% трафика на v1.1, 50% на v1.0
Шаг 4: 100% трафика на v1.1
Плюсы:
- Минимальный blast radius
- Мониторинг на каждом шаге
- Быстрый rollback
Минусы:
- Сложность настройки
- Долгий rollout
Сравнение стратегий
| Стратегия | Downtime | Rollback | Сложность | Когда |
|---|---|---|---|---|
| Rolling | Нет | Медленный | Низкая | Простые сервисы |
| Blue-Green | Нет | Мгновенный | Средняя | Критичные сервисы |
| Canary | Нет | Быстрый | Высокая | Высокий риск |
Реализация canary в Kubernetes
Через Istio или Argo Rollouts:
yamlapiVersion: argoproj.io/v1alpha1 kind: Rollout metadata: name: git-server spec: replicas: 3 strategy: canary: steps: - setWeight: 5 - pause: { duration: 5m } - setWeight: 25 - pause: { duration: 5m } - setWeight: 50 - pause: { duration: 5m } - setWeight: 100
4.9 Feature flags
Что это
Feature flags позволяют включать/выключать функциональность без деплоя.
Зачем нужны
- Безопасные релизы (постепенное включение)
- A/B тестирование
- Экстренное отключение фичи
- Тестирование в production
Типы feature flags
| Тип | Назначение | Пример |
|---|---|---|
| Release | Постепенный rollout | Новая фича для 10% пользователей |
| Experiment | A/B тестирование | Два варианта UI |
| Ops | Экстренное отключение | Kill switch |
| Permission | Доступ по ролям | Premium фичи |
Реализация в Go
gotype FeatureFlags struct { mu sync.RWMutex flags map[string]bool } func NewFeatureFlags() *FeatureFlags { return &FeatureFlags{ flags: make(map[string]bool), } } func (f *FeatureFlags) IsEnabled(name string) bool { f.mu.RLock() defer f.mu.RUnlock() return f.flags[name] } func (f *FeatureFlags) Set(name string, enabled bool) { f.mu.Lock() defer f.mu.Unlock() f.flags[name] = enabled }
Использование
gofunc (h *Handler) CreateRepo(w http.ResponseWriter, r *http.Request) { if h.featureFlags.IsEnabled("new_repo_validation") { // Новая валидация if err := validateV2(req); err != nil { h.writeError(w, err) return } } else { // Старая валидация if err := validateV1(req); err != nil { h.writeError(w, err) return } } // Остальная логика }
Управление feature flags
Для production используйте специализированные сервисы:
- LaunchDarkly
- Unleash
- Flagsmith
- ConfigCat
Или храните в конфиге с hot reload:
yaml# config.yaml features: new_repo_validation: true advanced_search: false webhook_v2: true
4.10 GitOps
Что это
GitOps — подход где желаемое состояние системы описано в git. Оператор (ArgoCD, Flux) синхронизирует кластер с git.
Принципы GitOps
- Declarative: состояние описано декларативно
- Versioned: состояние в git (версионировано)
- Pulled: оператор pull'ит изменения из git
- Reconciled: оператор continuously reconciles состояние
ArgoCD пример
yamlapiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: git-server spec: project: default source: repoURL: https://github.com/org/git-server targetRevision: main path: deploy/kubernetes destination: server: https://kubernetes.default.svc namespace: production syncPolicy: automated: prune: true selfHeal: true
Процесс деплоя через GitOps
- Разработчик мержит PR в main
- CI собирает образ и пушит в registry
- CI обновляет manifest в git (image tag)
- ArgoCD видит изменение
- ArgoCD синхронизирует кластер с git
- Кластер обновляется
Плюсы GitOps
- Аудит: все изменения в git
- Rollback: git revert
- Consistency: кластер всегда соответствует git
- Automation: нет ручных kubectl apply
Минусы GitOps
- Требует Kubernetes
- Кривая обучения
- Избыточен для простых деплоев
Привязка к шаблону проекта
Где deployment в шаблоне
deploy/
├── terraform/
│ ├── main.tf
│ ├── vpc.tf
│ ├── compute.tf # VDS instance
│ ├── disk.tf
│ ├── iam.tf
│ ├── lockbox.tf
│ ├── storage.tf
│ ├── backups.tf
│ ├── monitoring.tf
│ ├── alerts.tf
│ ├── outputs.tf
│ └── variables.tf
├── ansible/
│ ├── playbook.yml
│ ├── inventory.yml
│ ├── roles/
│ │ ├── app/
│ │ ├── nginx/
│ │ └── monitoring/
│ └── group_vars/
└── cloud-init/
└── bootstrap.sh
configs/systemd/
├── git-server.service
└── git-server-worker.service
Что изучаем на примере шаблона
- Terraform для VDS инфраструктуры
- Ansible для конфигурации
- Systemd units для сервисов
- Single binary strategy
- Graceful shutdown в коде
Задание: изучите deploy/
- Какая инфраструктура описана в Terraform?
- Что делает Ansible playbook?
- Какие systemd units?
- Как настроен graceful shutdown?
💱 Компромиссы
- Serverless vs VDS: функции масштабируются от нуля и платятся по вызовам, но cold start даёт 100ms-2s и лимит времени выполнения; у VDS нет cold start и есть long-running процессы, но оплата фиксированная, а автоскейлинга нет.
- Kubernetes vs VDS: автоскейлинг, self-healing и rolling updates без downtime, но операционная сложность и нужен DevOps; VDS прост и предсказуем по стоимости, но скейлинг ручной, а сервер без репликации — single point of failure.
- Rolling update vs Blue-Green: rolling не удваивает ресурсы, но во время rollout сосуществуют смешанные версии и откат медленный; blue-green переключает трафик мгновенно, но до полного переключения платятся двойные ресурсы.
- Cron vs timer triggers: cron через robfig/cron или CronJob живёт в вашем процессе без cold start и с состоянием, но инфраструктура на вас; timer trigger управляется провайдером и платится per invocation, но каждый запуск — это cold start, а функция stateless.
- Single binary vs раздельные артефакты: один бинарник с subcommands
(
serve,worker,migrate) даёт один артефакт, одну версию и простой rollback, но роли нельзя масштабировать по отдельности; раздельные бинарники масштабируют каждую роль под её нагрузку, зато артефактов и версий для отслеживания больше.
Практическое задание
Задание 1: Single binary
Реализуйте single binary с subcommands:
bashgit-server serve git-server worker git-server migrate git-server version
Используйте cobra для CLI.
Задание 2: Graceful shutdown
Реализуйте graceful shutdown для HTTP сервера:
gofunc runHTTPServer(ctx context.Context, app *App, cfg *Config) error
С:
- Signal handling (SIGINT, SIGTERM)
- Drain connections
- Timeout на shutdown
- Логирование
Задание 3: Systemd unit
Создайте systemd unit для вашего сервиса:
[Unit]
Description=My Service
After=network.target postgresql.service
[Service]
Type=simple
User=app
ExecStart=/usr/local/bin/myapp serve
Restart=always
RestartSec=5
KillSignal=SIGTERM
TimeoutStopSec=30
[Install]
WantedBy=multi-user.target
Задание 4: Ansible playbook
Напишите Ansible playbook для деплоя:
yaml- name: Deploy myapp hosts: staging become: yes tasks: - name: Copy binary - name: Copy config - name: Copy systemd unit - name: Enable and start service
Задание 5: Feature flags
Реализуйте feature flags middleware:
gofunc FeatureFlags(flags *FeatureFlags) func(http.Handler) http.Handler
Используйте для постепенного rollout новой фичи.
Задание 6: Canary deployment
Напишите Kubernetes manifest для canary deployment через Argo Rollouts:
yamlapiVersion: argoproj.io/v1alpha1 kind: Rollout metadata: name: myapp spec: strategy: canary: steps: - setWeight: 5 - pause: { duration: 5m } - setWeight: 25 - pause: { duration: 5m } - setWeight: 100
Задание 7: Сравнение моделей деплоя
Для вашего проекта напишите ADR:
# ADR-002: Выбор модели деплоя
## Статус
Accepted
## Контекст
- Характер нагрузки: стабильная, 100 RPS
- Команда: 3 человека, без DevOps
- Бюджет: ограниченный
## Решение
Используем VDS потому что...
## Альтернативы
- Serverless: cold start критичен
- Kubernetes: избыточно для 3 человек
## Последствия
- Простота деплоя
- Предсказуемая стоимость
- Нет автоскейлинга
Quiz "Проверь себя"
✅ Итоги модуля
Студент должен:
- Выбирать модель деплоя под задачу
- Проектировать single binary стратегию
- Понимать cron vs timer triggers
- Реализовывать graceful shutdown
- Применять стратегии rollout (canary, blue-green)
- Использовать feature flags
- Понимать принципы GitOps
- Ответить на все вопросы Quiz
🔗 Мостик к Модулю 5
Следующий модуль: Модуль 5. Observability at Scale - metrics design (RED, USE), high-cardinality labels, tracing in distributed systems, log correlation, alerting strategy, SLI/SLO/SLA, error budgets. Привязка к internal/observability/ шаблона.