Настройка автоскейлинга серверов мобильного приложения
Мобильный трафик непредсказуем. Push-рассылка на 500 000 устройств, публикация в AppStore-редакции, упоминание в телеграм-канале с 300k подписчиков — и сервер, который только что обрабатывал 200 rps, получает 3000 rps за 30 секунд. Без автоскейлинга — 503 и плохой отзыв в сторе.
Виды автоскейлинга и когда что применять
Horizontal Pod Autoscaler (HPA) в Kubernetes — добавляет поды при росте нагрузки, убирает при спаде. Базовая метрика — CPU utilization, но для мобильного API лучше: latency p99, количество запросов в очереди, или custom metric из Prometheus.
Vertical Pod Autoscaler (VPA) — изменяет requests/limits пода. Полезно для JVM-сервисов, где memory растёт по мере прогрева heap. Но VPA требует рестарт пода при изменении ресурсов — не подходит для stateful сервисов.
Cluster Autoscaler — добавляет/убирает Kubernetes nodes в облаке (AWS EC2, GCP GKE, Azure AKS). Работает совместно с HPA: HPA хочет 5 подов, но нет места — Cluster Autoscaler добавляет ноду.
KEDA (Kubernetes Event-Driven Autoscaling) — скейлинг по внешним метрикам: длина очереди в RabbitMQ, Kafka lag, число сообщений в Redis Streams. Для мобильного приложения с очередью push-уведомлений: воркеры масштабируются по числу задач в очереди, а не по CPU.
Настройка HPA для мобильного API
Проблема стандартного CPU-скейлинга: при пике запросов CPU сначала растёт, потом HPA решает добавить под (15–30 секунд), под стартует (ещё 10–30 секунд), проходит readiness probe. Итого: 30–60 секунд пока новый под начнёт принимать трафик. За это время часть мобильных клиентов получила 503.
Решения:
- Predictive scaling — заранее масштабируемся перед ожидаемым пиком (отправка пуша → сразу scale out)
-
ScaleUp faster, ScaleDown slower —
scaleUp.stabilizationWindowSeconds: 0(мгновенно масштабируемся вверх),scaleDown.stabilizationWindowSeconds: 300(ждём 5 минут перед уменьшением, чтобы не пилить) - Minreplicas: 2 — никогда не опускаться до 1 пода, чтобы rolling update не давал downtime
spec:
minReplicas: 2
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
behavior:
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Pods
value: 4
periodSeconds: 60
scaleDown:
stabilizationWindowSeconds: 300
Cold start проблема для мобильного трафика
Go и Node.js стартуют за 1–3 секунды — приемлемо. JVM-приложения (Spring Boot) — 10–20 секунд. Lambda (serverless) — cold start 500ms–3 секунды в зависимости от runtime и размера пакета.
Для JVM: держать минимум 2 пода всегда горячими. GraalVM Native Image — старт 0.1–0.3 секунды, но требует настройки reflection конфигурации. Spring Boot 3 + GraalVM Native — рабочая комбинация в production.
Для serverless (AWS Lambda, Google Cloud Functions): Provisioned Concurrency держит N инстансов прогретыми. Дороже, но cold start исчезает для этих инстансов.
Кейс: новостное приложение iOS. После публикации редакционного пуша — 40 000 одновременных открытий за 2 минуты. Один под на 2 vCPU справлялся с 400 rps. HPA настроен на CPU 60% — к моменту добавления пода пиковая нагрузка уже прошла. Решение: KEDA с метрикой из CloudWatch (число сообщений в SQS-очереди пушей) — при отправке пуша автоматически добавлялось 8 подов ещё до прихода трафика. Ноль 503 при следующих трёх рассылках.
Сроки: настройка HPA + Cluster Autoscaler для одного сервиса — 2–4 дня. KEDA с кастомными метриками + предиктивный скейлинг — 1–2 недели.







