-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
Parent Issue: Epic 3.6: Production Deployment (#194)
Summary
在 Gateway 层(OpenResty + Redis)实现 API rate limiting,保护后端服务免受滥用。
Status: ✅ Gateway Implementation Complete
Gateway rate limiting has been implemented in m3w-k8s (commit 91fb0f8).
Architecture
Browser → Gateway (OpenResty + Lua + Redis) → Backend
↓
Rate Limiter
- IP-based (未登录)
- userId-based (已登录,从 JWT 解析)
- endpoint-based (不同端点不同限制)
Rate Limit Strategy
限流维度
| 维度 | Redis Key 格式 | 数据来源 |
|---|---|---|
| IP | rl:ip:{ip}:{endpoint}:{window} |
ngx.var.remote_addr |
| User | rl:user:{userId}:{endpoint}:{window} |
JWT payload sub |
限流配置
| Endpoint | 未登录 (IP) | 已登录 (User) | 说明 |
|---|---|---|---|
/api/logs |
60/min | 200/min | 前端日志,高频 |
/api/auth/* |
10/min | N/A | 防暴力破解 |
/api/upload/* |
N/A (401) | 20/hour | 防存储滥用 |
GET/HEAD 默认 |
60/min | 300/min | 读操作 |
POST/PUT/DELETE 默认 |
30/min | 150/min | 写操作 |
算法
使用 固定窗口计数(简单高效):
- Key:
rl:{type}:{id}:{path}:{minute} - 使用
INCR+EXPIRE - 窗口结束自动清理
响应头
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1703404800
Retry-After: 30 (仅 429 时)
Implementation Status
✅ Gateway (m3w-k8s) - COMPLETED
Created: ansible/playbooks/templates/gateway-rate-limit.lua.j2
- Fixed window counter algorithm using Redis
- Path normalization (IDs →
:idto prevent key explosion) - Endpoint-specific rules (logs, auth, upload)
- Fail-open design (allows requests if Redis is down)
Modified: ansible/playbooks/templates/gateway-routing.lua.j2
- Integrated rate limiter call
- Added traceId generation/passthrough
- Added X-Gateway header
Modified: ansible/playbooks/templates/gateway-nginx.conf.j2
- Added X-Trace-Id to CORS allowed headers
- Added X-RateLimit-* headers to CORS expose headers
Modified: ansible/playbooks/templates/gateway-docker-compose.yml.j2
- Added rate-limit.lua volume mount
Modified: ansible/playbooks/gateway.yaml
- Added task to deploy rate-limit.lua
Deployment Required:
cd m3w-k8s
ansible-playbook -i ansible/inventory.ini ansible/playbooks/gateway.yaml --tags restart⏳ Frontend (m3w) - OPTIONAL
Frontend graceful degradation is optional but recommended:
frontend/src/lib/api/router.ts
- Handle 429 response
- For
/api/logs: silently drop (avoid log storm) - For other APIs: show toast notification
frontend/src/lib/logger-client.ts
- On 429, drop logs instead of retrying
Testing
After deploying to gateways:
# Test rate limiting
for i in {1..100}; do
curl -s -o /dev/null -w "%{http_code}\n" https://gateway1.m3w.test3207.fun/api/health
done
# Should see 429 after ~60 requests
# Check headers
curl -I https://gateway1.m3w.test3207.fun/api/health
# X-RateLimit-Limit: 60
# X-RateLimit-Remaining: 59
# X-RateLimit-Reset: 1735344120Monitoring (Grafana)
# Rate limit 触发统计
sum by (http_path) (count_over_time({service="m3w-gateway"} | json | http_status=429 [5m]))
# 按 IP 统计
topk(10, sum by (client_ip) (count_over_time({service="m3w-gateway"} | json | http_status=429 [1h])))
Related Issues
- Backend structured logging with traceId #249 Backend structured logging (provides traceId support) ✅
- Epic 3.6: Production Deployment Architecture #194 Epic 3.6: Production Deployment (parent)
- Epic 3.5: Observability & Operations #190 Epic 3.5: Observability (monitoring queries)
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels