Nginx as reverse proxy, load balancer and rate limiter over three catalog replicas
catalog
catalog saturates at ~400 req/s and a deploy takes it down. What fixes both at once?
k6 ──► edge :80 (Nginx) ──► catalog-1 ┐ ├─► catalog-2 ├──► db └─► catalog-3 ┘
X-Instance
x-catalog: &catalog build: ./services/catalog image: boxoffice-catalog deploy: { resources: { limits: { cpus: "1.0", memory: 768M } } } services: catalog-1: { <<: *catalog, hostname: catalog-1 } catalog-2: { <<: *catalog, hostname: catalog-2 } catalog-3: { <<: *catalog, hostname: catalog-3 }
upstream catalog { zone catalog 64k; server catalog-1:8082 resolve max_fails=3 fail_timeout=10s; server catalog-2:8082 resolve max_fails=3 fail_timeout=10s; server catalog-3:8082 resolve max_fails=3 fail_timeout=10s; keepalive 64; }
least_conn
resolve
proxy_connect_timeout 1s; proxy_read_timeout 5s; proxy_next_upstream error timeout http_502 http_503 http_504; proxy_next_upstream_tries 2;
stop
pause
A dead replica is easy. A slow one is dangerous: the timeout decides its cost.
/actuator/health/readiness
Why not proxy_read_timeout 100ms to catch frozen replicas instantly?
proxy_read_timeout 100ms
limit_req_zone $http_x_api_key zone=per_key:10m rate=20r/s; limit_req zone=per_key burst=40 nodelay; limit_req_status 429;
sub
LIST_SHARE=0
Scaling efficiency = capacity(3) / (3 × capacity(1)). Watch docker stats: who is at 100%?
docker stats
db
max_fails
502 no live upstreams
Outline: (1) why scale out; (2) the topology; (3) replicas in Compose; (4) nginx.conf; (5) distribution; (6) failures: stop vs pause; (7) rate limiting; (8) measuring scale-out efficiency.