This commit is contained in:
2026-09-11 01:09:37 -05:00
parent de7a2d299f
commit f7ae31536a
4 changed files with 6214 additions and 7 deletions
+68 -7
View File
@@ -192,7 +192,12 @@ All data endpoints return structured JSON with pagination metadata:
## Rate Limiting & Caching ## Rate Limiting & Caching
- **Rate Limiting**: Configured per client IP at **20 requests per minute per instance** (~60 req/min across the 3-instance cluster). If exceeded, the API responds with `HTTP 429 Too Many Requests`. - **Rate Limiting**: Configured per client IP at **20 requests per minute per instance** (~60 req/min across the 3-instance cluster). If exceeded, the API responds with `HTTP 429 Too Many Requests`.
- **Response Caching**: NGINX provides an in-memory cache (`api_cache`) for **30 seconds** (`keys_zone=api_cache:10m`). Cached responses include the header `X-Cache-Status: HIT` (or `MISS`). - **Custom Limits**: Configurable via `RATE_LIMIT_MAX` (default `20`) and `RATE_LIMIT_EXPIRATION_SECONDS` (default `60s`).
- **Internal Benchmark Bypass**: If `BENCHMARK_KEY` is configured in the environment, passing matching token in `X-Benchmark-Key` header skips rate limiting for automated benchmarks.
- **Multi-Layer Caching**:
- **Edge CDN (Cloudflare)**: Caches GET requests with `s-maxage=86400` (24h) and `stale-while-revalidate=600`.
- **NGINX Reverse Proxy**: Provides an in-memory cache (`api_cache`) for **30 seconds** (`keys_zone=api_cache:10m`).
- Responses include `CF-Cache-Status` (`HIT`/`MISS`) and `X-Cache-Status` (`HIT`/`MISS`) headers.
--- ---
@@ -212,6 +217,8 @@ DB_PASSWORD=your_password
DB_NAME=appdb DB_NAME=appdb
DB_PORT=5432 DB_PORT=5432
ADMIN_SECRET=your_admin_secret ADMIN_SECRET=your_admin_secret
BENCHMARK_KEY=your_internal_benchmark_token
RATE_LIMIT_MAX=20
``` ```
### Running Locally with Docker ### Running Locally with Docker
@@ -302,16 +309,70 @@ swag init -g main.go -o docs
go test -v ./... go test -v ./...
``` ```
### Load Testing ### Advanced Load Testing (`test/loadtest.go`)
The built-in load test utility supports weighted page distributions: The built-in load testing engine simulates high-volume, realistic traffic patterns across edge caches, reverse proxies, and the origin PostgreSQL database.
See the complete [Load Testing Guide](docs/loadtesting.md) for full details.
#### Key Capabilities:
- **Dynamic Query Randomization (`-varyParams`, `-complexity`)**: Permutes combinations of seasons, teams, sort columns, ascending/descending, page sizes, playoff filters, and heavy database relation joins (`include=lineScores,playerGameBasicStats,teamGameAdvStats`).
- **Cold-Cache Stress Testing (`-cacheBust`)**: Injects unique request nonces to ensure a 100% cache-miss rate for benchmarking raw database execution.
- **Cache Telemetry Split**: Inspects `CF-Cache-Status` (`HIT`/`MISS`) and `Age` headers to provide separate latency profiles for Edge Cache Hits vs. Origin / Database Misses.
- **Latency Percentiles**: Reports **Min**, **p50 (Median)**, **p75**, **p90**, **p95**, **p99**, **Max**, and **Average** latency.
- **Distributed Client Simulation (`-rotateIPs`)**: Injects rotating `X-Real-IP` and `X-Forwarded-For` headers to accurately simulate thousands of distinct clients.
- **Benchmark Token Support (`-benchmarkKey`)**: Passes `X-Benchmark-Key` header to bypass rate limits during testing.
- **Multi-Endpoint Traffic Mix (`-endpointMix`)**: Distributes traffic across `/api/playeradvancedstats`, `/api/playertotals`, `/api/games`, and `/api/playershotchart`.
#### Load Test CLI Flags:
| Flag | Default | Description |
| :--- | :--- | :--- |
| `-url` | `http://localhost:5000/api/playeradvancedstats` | Target endpoint or base URL |
| `-n` | `100` | Number of requests to send |
| `-c` | `10` | Concurrency level (worker goroutines) |
| `-varyParams` | `false` | Enable query parameter & filter randomization |
| `-complexity` | `standard` | Query complexity: `standard` or `high` |
| `-cacheBust` | `false` | Force 100% cold-cache misses on CDN/proxy |
| `-benchmarkKey` | `$BENCHMARK_KEY` | Token for `X-Benchmark-Key` header |
| `-rotateIPs` | `false` | Rotate synthetic client IPs |
| `-endpointMix` | `""` | Multi-endpoint traffic mix (e.g. `playeradvancedstats:40,playertotals:30,games:30`) |
| `-pageMix` | `""` | Weighted page mix (e.g. `1-3:60,4-10:30,11-20:10`) |
| `-retryOnRateLimit` | `false` | Retry 429 responses with backoff |
| `-log` | `loadtest.log` | Output log file destination |
#### Example Usage:
```bash ```bash
# 1. Realistic Traffic with Parameter Variance (Recommended)
go run ./test/loadtest.go \ go run ./test/loadtest.go \
-url "https://nba.turbo-data.com/api/playertotals?page=1&pageSize=50" \ -url 'https://nba.turbo-data.com/api/playeradvancedstats' \
-n 500 \ -n 3000 \
-c 20 \ -c 20 \
-pageMix "1-3:60,4-10:30,11-20:10" \ -varyParams \
-seed 42 \ -complexity high \
-rotateIPs \
-benchmarkKey 'your-benchmark-token' \
-pageMix '1-3:60,4-10:30,11-20:10' \
-log ./test/results.log
# 2. Pure Cold-Cache / Origin Database Benchmark (100% Cache Misses)
go run ./test/loadtest.go \
-url 'https://nba.turbo-data.com/api/playeradvancedstats' \
-n 1000 \
-c 15 \
-varyParams \
-cacheBust \
-benchmarkKey 'your-benchmark-token' \
-log ./test/results.log
# 3. Multi-Endpoint Traffic Mix
go run ./test/loadtest.go \
-url 'https://nba.turbo-data.com' \
-endpointMix 'playeradvancedstats:40,playertotals:30,games:30' \
-varyParams \
-n 2000 \
-c 20 \
-benchmarkKey 'your-benchmark-token' \
-log ./test/results.log -log ./test/results.log
``` ```
+36
View File
@@ -0,0 +1,36 @@
# Quick Start Recipes
```bash
# 1. Realistic Traffic with Parameter Variance (Recommended)
go run ./test/loadtest.go \
-url 'https://nba.turbo-data.com/api/playeradvancedstats' \
-n 3000 \
-c 20 \
-varyParams \
-complexity high \
-rotateIPs \
-benchmarkKey 'your-benchmark-token' \
-pageMix '1-3:60,4-10:30,11-20:10' \
-log ./test/results.log
# 2. Pure Cold-Cache / Origin Database Benchmark (100% Cache Misses)
go run ./test/loadtest.go \
-url 'https://nba.turbo-data.com/api/playeradvancedstats' \
-n 1000 \
-c 15 \
-varyParams \
-cacheBust \
-benchmarkKey 'your-benchmark-token' \
-log ./test/results.log
# 3. Multi-Endpoint Traffic Mix
go run ./test/loadtest.go \
-url 'https://nba.turbo-data.com' \
-endpointMix 'playeradvancedstats:40,playertotals:30,games:30' \
-varyParams \
-n 2000 \
-c 20 \
-benchmarkKey 'your-benchmark-token' \
-log ./test/results.log
```
+110
View File
@@ -0,0 +1,110 @@
# Load Testing & Traffic Simulation Guide
The `NBA_Go` repository includes an advanced, high-performance load testing engine written in Go (`test/loadtest.go`). It is designed to stress-test the API across edge caches (Cloudflare), reverse proxies (NGINX), the Go Fiber application server, and PostgreSQL database queries under realistic traffic patterns.
---
## Why Enhanced Load Testing?
In production, APIs often employ multi-tier caching (Cloudflare Edge with `s-maxage` + NGINX in-memory cache). A basic load test querying a fixed URL or a small set of pages will hit the edge cache after the first request, returning sub-15ms responses from CDN memory. While this validates CDN delivery, it completely bypasses the Go origin server, connection pool, and database query engine.
The enhanced load tester solves this by introducing:
1. **Dynamic Query Variation (`-varyParams`, `-complexity`)**: Randomizes combinations of seasons, teams, sort columns, sort order, page sizes, playoff filters, player IDs, and heavy database relation joins.
2. **Cold-Cache Benchmark Mode (`-cacheBust`)**: Injects unique high-resolution nonces to guarantee a 100% cache-miss rate when benchmarking origin and database query execution.
3. **Cache Telemetry Split**: Analyzes `CF-Cache-Status` (`HIT`/`MISS`), `Age`, and `X-Cache` response headers, presenting separate latency profiles for Edge Cache Hits vs. Origin / Database Misses.
4. **Latency Percentiles**: Measures **Min**, **p50 (Median)**, **p75**, **p90**, **p95**, **p99**, **Max**, and **Average** across all requests.
5. **Distributed Client Simulation (`-rotateIPs`)**: Injects rotating `X-Real-IP` and `X-Forwarded-For` headers to simulate thousands of distinct clients.
6. **Benchmark Token Support (`-benchmarkKey`)**: Passes the `X-Benchmark-Key` header to bypass rate limits on origin servers configured with `BENCHMARK_KEY`.
7. **Multi-Endpoint Traffic Generation (`-endpointMix`)**: Distributes traffic across `/api/playeradvancedstats`, `/api/playertotals`, `/api/games`, and `/api/playershotchart`.
---
## CLI Flags Reference
| Flag | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `-url` | `string` | `http://localhost:5000/api/playeradvancedstats` | Target endpoint or base URL to test |
| `-n` | `int` | `100` | Total number of HTTP requests to send |
| `-c` | `int` | `10` | Number of concurrent worker goroutines |
| `-varyParams` | `bool` | `false` | Randomize query parameters (`season`, `team`, `sortBy`, `pageSize`, `isPlayoff`, etc.) |
| `-complexity` | `string` | `standard` | Query complexity level: `standard` or `high` (attaches heavy relation preloads for `/api/games`) |
| `-cacheBust` | `bool` | `false` | Append unique query nonce (`_cb=...`) to force 100% cache misses on edge/proxy layers |
| `-benchmarkKey`| `string` | `$BENCHMARK_KEY` | Token for `X-Benchmark-Key` header to bypass origin rate limiting |
| `-rotateIPs` | `bool` | `false` | Rotate synthetic client IPs (`X-Real-IP` / `X-Forwarded-For`) |
| `-retryOnRateLimit` | `bool` | `false` | Retry HTTP 429 responses with exponential backoff (up to 3 retries) |
| `-endpointMix`| `string` | `""` | Weighted multi-endpoint mix (e.g., `playeradvancedstats:40,playertotals:30,games:30`) |
| `-pageMix` | `string` | `""` | Weighted page mix (e.g., `1-3:60,4-10:30,11-20:10`) |
| `-timeout` | `duration` | `30s` | Per-request HTTP timeout |
| `-key` | `string` | `""` | API key passed in `x-api-key` header |
| `-log` | `string` | `loadtest.log` | Output log file destination |
| `-seed` | `int64` | `-1` | Random seed (`-1` uses current timestamp) |
---
## Usage Recipes
### 1. Realistic Traffic with Parameter Variance (Recommended)
Simulates realistic user traffic with diverse filter permutations across seasons, teams, and sorting:
```bash
go run ./test/loadtest.go \
-url 'https://nba.turbo-data.com/api/playeradvancedstats' \
-n 3000 \
-c 20 \
-varyParams \
-complexity high \
-rotateIPs \
-benchmarkKey 'your-benchmark-token' \
-pageMix '1-3:60,4-10:30,11-20:10' \
-log ./test/results.log
```
### 2. Pure Origin / Database Stress Test (100% Cold Cache)
Forces all requests to miss edge and reverse-proxy caches to benchmark raw database query execution:
```bash
go run ./test/loadtest.go \
-url 'https://nba.turbo-data.com/api/playeradvancedstats' \
-n 1000 \
-c 15 \
-varyParams \
-cacheBust \
-benchmarkKey 'your-benchmark-token' \
-log ./test/results.log
```
### 3. Multi-Endpoint Traffic Mix
Exercises multiple domains across the application simultaneously according to traffic weights:
```bash
go run ./test/loadtest.go \
-url 'https://nba.turbo-data.com' \
-endpointMix 'playeradvancedstats:40,playertotals:30,games:30' \
-varyParams \
-n 2000 \
-c 20 \
-benchmarkKey 'your-benchmark-token' \
-log ./test/results.log
```
### 4. Legacy Execution (Fixed URL with Page Mix)
Runs the traditional page-mix workload:
```bash
go run ./test/loadtest.go \
-url 'https://nba.turbo-data.com/api/playeradvancedstats?page=1&pageSize=40&sortBy=winShares&ascending=false' \
-n 500 \
-c 10 \
-pageMix '1-3:60,4-10:30,11-20:10' \
-log ./test/results.log
```
---
## Running Unit Tests
Unit tests validate parameter permutations, cache header parsing, percentiles calculation, and endpoint mixing:
```bash
go test -v ./test/...
```
+6000
View File
File diff suppressed because it is too large Load Diff