Links#
- Amazon ECS Service Auto Scaling
- Target tracking scaling policies
- Amazon ECS CloudWatch metrics
- ALB CloudWatch metrics
- Go runtime package
- aws application-autoscaling put-scaling-policy
1. Scaling Strategy#
Go 服务通常 CPU signal 很干净,但 HTTP 服务仍优先用 request rate per task,因为它更接近业务 demand。
| Workload | Primary Scaling Metric | Target |
|---|---|---|
| HTTP API behind ALB | ALBRequestCountPerTarget |
load test safe RPS per task 的 60-75% |
| CPU-bound API / gRPC | ECSServiceAverageCPUUtilization |
60-70% |
| SQS / stream worker | custom backlog_per_task |
backlog 在 SLO 内下降 |
| memory-sensitive service | memory guard + Go runtime metrics | 不用 RSS spike 直接推导 demand |
Go guardrails:
p95 latency:
<= service SLO
CPU:
target load <= 70%
sustained > 80% means scale-out or profile
goroutine:
count stable under stable traffic
no unbounded goroutine growth
GC:
pause stays inside latency budget
heap goal / live heap trend stable
memory:
use GOMEMLIMIT below ECS memory limit
keep container memory headroom >= 20%Decision:
web API:
use ALBRequestCountPerTarget for predictable routing capacity
use CPU policy when request cost varies heavily
worker:
use backlog_per_task
add oldest-message-age alert
runtime:
set GOMAXPROCS intentionally when task vCPU is small
set GOMEMLIMIT to avoid container OOM2. ECS Policy#
Register scalable target:
aws application-autoscaling register-scalable-target \
--service-namespace ecs \
--scalable-dimension ecs:service:DesiredCount \
--resource-id service/prod-apps/order-api \
--min-capacity 2 \
--max-capacity 25 \
--region ap-east-1ALB request count target tracking:
aws application-autoscaling put-scaling-policy \
--service-namespace ecs \
--scalable-dimension ecs:service:DesiredCount \
--resource-id service/prod-apps/order-api \
--policy-name order-api-go-rps-per-task \
--policy-type TargetTrackingScaling \
--target-tracking-scaling-policy-configuration '{
"TargetValue": 600,
"PredefinedMetricSpecification": {
"PredefinedMetricType": "ALBRequestCountPerTarget",
"ResourceLabel": "app/prod-public-alb/abc123/targetgroup/prod-order-api/def456"
},
"ScaleOutCooldown": 60,
"ScaleInCooldown": 300
}' \
--region ap-east-1CPU target tracking:
aws application-autoscaling put-scaling-policy \
--service-namespace ecs \
--scalable-dimension ecs:service:DesiredCount \
--resource-id service/prod-apps/order-api \
--policy-name order-api-go-cpu \
--policy-type TargetTrackingScaling \
--target-tracking-scaling-policy-configuration '{
"TargetValue": 65,
"PredefinedMetricSpecification": {
"PredefinedMetricType": "ECSServiceAverageCPUUtilization"
},
"ScaleOutCooldown": 60,
"ScaleInCooldown": 300
}' \
--region ap-east-13. Load Test For Threshold#
Goal: 找到 latency 还稳定时的 per-task throughput。
test setup:
desiredCount = 1
same task CPU/memory as production
same GOMAXPROCS / GOMEMLIMIT as production
expose pprof or runtime metrics in test env
increase load:
100 RPS -> 300 -> 600 -> 900 -> 1200
each step >= 10m
stop point:
p95 latency > SLO
5xx >= 1%
CPU avg >= 80%
goroutine count keeps growing
GC pause or heap growth breaks baselineExample result:
task size:
1 vCPU / 512MB
observed:
800 RPS: p95 160ms, CPU 62%, memory stable
1000 RPS: p95 420ms, CPU 83%, goroutine count rising
safe RPS per task:
800
autoscaling target:
800 * 0.75 = 600
choose ALBRequestCountPerTarget target = 600Useful commands:
hey -z 10m -c 300 https://api.example.com/orders
go tool pprof -top http://localhost:6060/debug/pprof/profile?seconds=304. Readiness Checklist#
scaling:
minCapacity >= 2
maxCapacity checked against DB and downstream quotas
scale-in cooldown slower than scale-out
go runtime:
GOMAXPROCS matches task CPU allocation
GOMEMLIMIT lower than ECS memory limit
SIGTERM graceful shutdown implemented
observability:
ALB RPS / latency / 5xx
ECS CPU / memory
goroutine count
GC pause / heap allocation
task restart count