|
1 | | -// README.md |
| 1 | +# Distributed Rate Limiter |
| 2 | + |
| 3 | +A horizontally scalable rate-limiting service enforcing per-client quotas with strong |
| 4 | +correctness guarantees under concurrent load. |
| 5 | + |
| 6 | +## What this demonstrates |
| 7 | + |
| 8 | +| Signal | How | |
| 9 | +|--------|-----| |
| 10 | +| Distributed systems | Atomic decisions across stateless replicas via Redis Lua scripts | |
| 11 | +| Concurrency & correctness | Goroutine-storm integration test; correctness argument in `docs/tradeoffs.md` | |
| 12 | +| Performance validation | k6 load test with committed p99 latency results | |
| 13 | +| Production observability | Prometheus counters + latency histograms + Grafana dashboard | |
| 14 | +| Deployment & reliability | Kubernetes with rolling updates, HPA, health probes, Redis StatefulSet | |
| 15 | +| Engineering tradeoffs | Algorithm choice, atomicity, failure behaviour in `docs/tradeoffs.md` | |
| 16 | + |
| 17 | +## Quick start |
| 18 | + |
| 19 | +```bash |
| 20 | +# Start Redis |
| 21 | +docker run -d -p 6379:6379 redis:7-alpine |
| 22 | + |
| 23 | +# Run the service |
| 24 | +make run |
| 25 | + |
| 26 | +# Test a request |
| 27 | +curl -X POST http://localhost:8080/check -H "X-API-Key: my-key" |
| 28 | + |
| 29 | +# Unit tests |
| 30 | +make test |
| 31 | + |
| 32 | +# Integration tests (requires running service + Redis) |
| 33 | +make test-integration |
| 34 | + |
| 35 | +# Load test (requires k6) |
| 36 | +make load-test |
| 37 | +``` |
| 38 | + |
| 39 | +## API |
| 40 | + |
| 41 | +POST /check with X-API-Key header -> 200 (allowed) or 429 (rejected) |
| 42 | +GET /metrics -> Prometheus metrics |
| 43 | +gRPC AllowRequest on :50051 (see proto/ratelimiter.proto) |
| 44 | + |
| 45 | +## Project structure |
| 46 | + |
| 47 | +| Path | Purpose | |
| 48 | +|------|---------| |
| 49 | +| cmd/server/ | Entry point | |
| 50 | +| internal/algorithm/ | Pure Go sliding window + token bucket | |
| 51 | +| internal/limiter/ | Core domain — AllowRequest() | |
| 52 | +| internal/store/ | Redis abstraction + Lua script loading | |
| 53 | +| internal/metrics/ | Prometheus instrumentation | |
| 54 | +| internal/grpc/ | gRPC handler | |
| 55 | +| internal/http/ | HTTP handler | |
| 56 | +| scripts/lua/ | Atomic Redis Lua scripts | |
| 57 | +| tests/integration/ | Correctness, concurrency, failure tests | |
| 58 | +| tests/load/ | k6 and vegeta load tests + benchmark results | |
| 59 | +| deploy/k8s/ | Kubernetes manifests | |
| 60 | +| deploy/grafana/ | Grafana dashboard | |
| 61 | +| docs/ | Architecture and tradeoff docs | |
| 62 | + |
| 63 | +## Documentation |
| 64 | + |
| 65 | +- docs/architecture.md — component diagram, request lifecycle, test strategy |
| 66 | +- docs/tradeoffs.md — algorithm choice, atomicity, failure behaviour, memory model |
| 67 | +- tests/load/benchmarks/results.md — measured latency under load |
0 commit comments