Налаштування автоскейлингу серверів веб-додатку
Автоскейлинг автоматично додає серверів при зростанні навантаження та видаляє їх у періоди затишшя. Головна мета — не переплачувати за простаювальні потужності та не втрачати запити при піках трафіку.
Метрики для скейлингу
Правильний вибір метрики визначає якість автоскейлингу:
| Метрика | Коли використовувати | Поріг |
|---|---|---|
| CPU Utilization | CPU-intensive додатки | 60–70% |
| Request Count (RPS) | Stateless HTTP-сервісів | за бізнес-тесту |
| Memory Utilization | Memory-intensive | 70–80% |
| Queue Depth (SQS/RabbitMQ) | Worker-процеси | 100–500 повідомлень |
| Custom metric (p95 latency) | Latency-sensitive API | 200–500 мс |
CPU-метрика запаздує — сервер спершу тормозить, потім скейлиться. RPS-метрика реагує швидше. Для типового веб-додатку комбінують CPU + Request Count.
AWS Auto Scaling Group
Найпоширеніший сценарій — EC2 ASG з Application Load Balancer.
# Terraform: Launch Template + ASG
resource "aws_launch_template" "app" {
name_prefix = "myapp-"
image_id = data.aws_ami.ubuntu.id
instance_type = "t3.medium"
user_data = base64encode(<<-EOF
#!/bin/bash
cd /var/www/myapp
git pull origin main
systemctl restart php8.3-fpm
systemctl reload nginx
EOF
)
network_interfaces {
associate_public_ip_address = false
security_groups = [aws_security_group.app.id]
}
iam_instance_profile {
name = aws_iam_instance_profile.app.name
}
lifecycle {
create_before_destroy = true
}
}
resource "aws_autoscaling_group" "app" {
name = "myapp-asg"
vpc_zone_identifier = aws_subnet.private[*].id
target_group_arns = [aws_lb_target_group.app.arn]
health_check_type = "ELB"
health_check_grace_period = 300
min_size = 2
max_size = 20
desired_capacity = 2
launch_template {
id = aws_launch_template.app.id
version = "$Latest"
}
instance_refresh {
strategy = "Rolling"
preferences {
min_healthy_percentage = 50
}
}
tag {
key = "Name"
value = "myapp-app"
propagate_at_launch = true
}
}
Kubernetes HPA та KEDA
Kubernetes Horizontal Pod Autoscaler працює з CPU та Memory з коробки. KEDA додає зовнішні метрики: SQS, RabbitMQ, Kafka, Prometheus.
# HPA за CPU + Memory
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: myapp-hpa
namespace: myapp
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: myapp-web
minReplicas: 2
maxReplicas: 50
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 65
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 75
behavior:
scaleUp:
stabilizationWindowSeconds: 30
policies:
- type: Pods
value: 4
periodSeconds: 60
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 25
periodSeconds: 60
Scheduled Scaling
Для передбачуваних піків (нічна рассилка, розпродажи за розкладом) добавляють scheduled actions.
import boto3
client = boto3.client('application-autoscaling', region_name='eu-west-1')
# Масштабування вверх перед піком (пятниця 18:00 UTC)
client.put_scheduled_action(
ServiceNamespace='ecs',
ResourceId='service/myapp-cluster/myapp-web',
ScalableDimension='ecs:service:DesiredCount',
ScheduledActionName='scale-up-friday-evening',
Schedule='cron(0 18 ? * FRI *)',
ScalableTargetAction={
'MinCapacity': 10,
'MaxCapacity': 50,
}
)
Graceful Shutdown
При scale-in інстанс отримує сигнал завершення. Додаток повинен встигнути завершити поточні запити.
// Node.js Express
const server = app.listen(3000);
process.on('SIGTERM', () => {
console.log('SIGTERM received, shutting down gracefully');
server.close(() => {
console.log('HTTP server closed');
process.exit(0);
});
// Принудкове завершення через 30 секунд
setTimeout(() => {
console.error('Forced shutdown');
process.exit(1);
}, 30000);
});
Типичні проблеми
Thrashing — постійне додавання/видалення інстансів через короткий cooldown. Рішення: збільшити scale_in_cooldown до 300–600 секунд.
Повільний старт додатку — інстанс створен, але трафік іде до готовності. Рішення: health check grace period + readiness probe + Warm Pool.
Дорогий scale-in — видалення інстанса з незавершеними фоновими завданнями. Рішення: lifecycle hook + drain очереди перед CONTINUE.
Неправильна метрика — CPU 20%, але додаток тормозить через I/O wait. Рішення: custom metric (p95 latency через CloudWatch або Prometheus).
Лінія часу
| Конфігурація | Лінія часу |
|---|---|
| EC2 ASG + ALB + CPU scaling | 2–3 дні |
| ECS Fargate + target tracking | 1–2 дні |
| Kubernetes HPA | 1 день |
| KEDA + зовнішні метрики | 2–3 дні |
| Scheduled scaling + Warm Pool | +1–2 дні |







