Why Rate-Limit at the Load Balancer
Application-level rate limiting catches abuse after the request has already consumed backend resources -- TCP connection, TLS handshake, request parsing. HAProxy stick-tables let you shed load at the edge before any of that happens.
The Docker Compose Lab
# docker-compose.yml version : ' 3.8' services : haproxy : image : haproxy:2.9 ports : - " 80:80" - " 8404:8404" # stats volumes : - ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro depends_on : - backend1 - backend2 - backend3
backend1 : build : ./backend environment : - BACKEND_ID=1 backend2 : build : ./backend environment : - BACKEND_ID=2 backend3 : build : ./backend environment : - BACKEND_ID=3
Enter fullscreen mode
Exit fullscreen mode
The backend is a minimal Go HTTP server:
// backend/main.go package main
import ( "fmt" "net/http" "os" "time" )
func main () { id := os . Getenv ( "BACKEND_ID" ) http . HandleFunc ( "/api/data" , func ( w http . ResponseWriter , r * http .…