在构建生产级 AI 应用时,一个可靠的 API 网关中间件是基础设施的核心组成部分。本文将深入探讨如何设计并实现一个同时具备认证鉴权、流量限制和日志审计三大能力的网关中间件,并提供可直接部署到生产环境的完整代码实现。
一、整体架构设计
我们的网关中间件采用分层架构,核心组件包括:
- AuthMiddleware:API Key 验证与用户身份识别
- RateLimitMiddleware:令牌桶算法实现的流量控制
- LoggingMiddleware:请求/响应全链路日志记录
- ProxyHandler:智能路由与上游 API 转发
整体数据流如下:
Client Request
│
▼
┌─────────────────┐
│ AuthMiddleware │ ← 验证 API Key,解析用户身份
└────────┬────────┘
│
▼
┌─────────────────────┐
│ RateLimitMiddleware │ ← 令牌桶限流,防刷防滥用
└────────┬────────────┘
│
▼
┌─────────────────┐
│LoggingMiddleware│ ← 记录请求元数据、耗时、Token用量
└────────┬────────┘
│
▼
┌─────────────────┐
│ ProxyHandler │ ← 转发至 HolySheheep API
└────────┬────────┘
│
▼
HolySheheep API
(https://api.holysheep.ai/v1)
│
▼
Response to Client
二、认证模块实现
认证是网关的第一道防线。我们采用 Bearer Token 模式,支持 API Key 的生成、验证与缓存。
import hashlib
import hmac
import time
from typing import Optional, Dict
from functools import wraps
from flask import request, jsonify, g
import redis
class AuthMiddleware:
"""HolySheheep API Key 认证中间件"""
def __init__(self, redis_client: redis.Redis):
self.redis = redis_client
self.key_prefix = "apikey:"
self.key_ttl = 3600 # 缓存1小时
def generate_signature(self, api_key: str, timestamp: int) -> str:
"""生成 HMAC-SHA256 签名"""
message = f"{api_key}:{timestamp}"
return hmac.new(
api_key.encode(),
message.encode(),
hashlib.sha256
).hexdigest()
def validate_api_key(self, api_key: str) -> Optional[Dict]:
"""
验证 API Key,返回用户信息
优先从 Redis 缓存读取,降低 HolySheheep API 校验压力
"""
# 缓存查询
cache_key = f"{self.key_prefix}{api_key}"
cached = self.redis.get(cache_key)
if cached:
return json.loads(cached)
# 实际生产中应调用 HolySheheep 验证接口
# https://api.holysheep.ai/v1/auth/validate
user_info = self._verify_with_provider(api_key)
if user_info:
# 写入缓存
self.redis.setex(
cache_key,
self.key_ttl,
json.dumps(user_info)
)
return user_info
def _verify_with_provider(self, api_key: str) -> Optional[Dict]:
"""调用 HolySheheep API 验证 Key 有效性"""
import requests
response = requests.post(
"https://api.holysheep.ai/v1/auth/validate",
headers={
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
},
timeout=5
)
if response.status_code == 200:
return response.json()
return None
def require_auth(self, f):
"""装饰器:强制要求认证"""
@wraps(f)
def decorated(*args, **kwargs):
auth_header = request.headers.get("Authorization", "")
if not auth_header.startswith("Bearer "):
return jsonify({
"error": "Missing or invalid Authorization header",
"code": "AUTH_REQUIRED"
}), 401
api_key = auth_header[7:] # 去掉 "Bearer " 前缀
user_info = self.validate_api_key(api_key)
if not user_info:
return jsonify({
"error": "Invalid API key",
"code": "INVALID_KEY"
}), 401
# 存储用户信息供后续中间件使用
g.user_id = user_info.get("user_id")
g.api_key = api_key
g.quota = user_info.get("quota", {})
return f(*args, **kwargs)
return decorated
三、限流模块实现
使用令牌桶算法实现精细化的流量控制,支持按用户、按接口、按 Token 配额等多维度限流。
import time
import threading
from collections import defaultdict
from dataclasses import dataclass
from typing import Dict, Tuple
@dataclass
class RateLimitConfig:
"""限流配置"""
requests_per_minute: int = 60
tokens_per_minute: int = 100000 # input tokens
output_tokens_per_minute: int = 50000 # output tokens
burst_size: int = 10
class TokenBucket:
"""令牌桶实现"""
def __init__(self, rate: float, capacity: int):
self.rate = rate # 每秒补充令牌数
self.capacity = capacity
self.tokens = capacity
self.last_update = time.time()
self.lock = threading.Lock()
def consume(self, tokens: int = 1) -> Tuple[bool, float]:
"""
尝试消费令牌
返回: (是否成功, 剩余令牌数)
"""
with self.lock:
now = time.time()
# 补充令牌
elapsed = now - self.last_update
self.tokens = min(
self.capacity,
self.tokens + elapsed * self.rate
)
self.last_update = now
if self.tokens >= tokens:
self.tokens -= tokens
return True, self.tokens
return False, self.tokens
class RateLimitMiddleware:
"""多维度限流中间件"""
def __init__(self, config: RateLimitConfig = None):
self.config = config or RateLimitConfig()
self.user_buckets: Dict[str, Dict[str, TokenBucket]] = defaultdict(dict)
self.global_bucket = TokenBucket(
rate=self.config.requests_per_minute / 60,
capacity=self.config.requests_per_minute
)
self.lock = threading.Lock()
def _get_user_bucket(self, user_id: str) -> Dict[str, TokenBucket]:
"""获取用户专属的令牌桶"""
with self.lock:
if user_id not in self.user_buckets:
self.user_buckets[user_id] = {
"requests": TokenBucket(
self.config.requests_per_minute / 60,
self.config.burst_size
),
"input_tokens": TokenBucket(
self.config.tokens_per_minute / 60,
self.config.tokens_per_minute
),
"output_tokens": TokenBucket(
self.config.output_tokens_per_minute / 60,
self.config.output_tokens_per_minute
)
}
return self.user_buckets[user_id]
def check_rate_limit(
self,
user_id: str,
input_tokens: int = 0,
output_tokens: int = 0
) -> Tuple[bool, Dict]:
"""
检查是否超过限流
返回: (是否允许请求, 限流信息)
"""
buckets = self._get_user_bucket(user_id)
# 检查请求数限流
req_ok, _ = buckets["requests"].consume(1)
if not req_ok:
return False, {"type": "requests", "limit": self.config.requests_per_minute}
# 检查 Input Token 限流
if input_tokens > 0:
tok_ok, remaining = buckets["input_tokens"].consume(input_tokens)
if not tok_ok:
return False, {"type": "input_tokens", "limit": self.config.tokens_per_minute}
# 检查 Output Token 限流
if output_tokens > 0:
out_ok, remaining = buckets["output_tokens"].consume(output_tokens)
if not out_ok:
return False, {"type": "output_tokens", "limit": self.config.output_tokens_per_minute}
return True, {"allowed": True}
def enforce_rate_limit(self, f):
"""装饰器:强制执行限流"""
@wraps(f)
def decorated(*args, **kwargs):
user_id = getattr(g, 'user_id', 'anonymous')
# 从请求体中预估 Token 用量
input_tokens = self._estimate_tokens(request.json)
output_tokens = 0 # Output token 在响应后才知道
allowed, limit_info = self.check_rate_limit(
user_id, input_tokens, output_tokens
)
if not allowed:
return jsonify({
"error": f"Rate limit exceeded: {limit_info['type']}",
"limit": limit_info["limit"],
"code": "RATE_LIMIT_EXCEEDED"
}), 429
g.estimated_tokens = input_tokens
return f(*args, **kwargs)
return decorated
def _estimate_tokens(self, payload: dict) -> int:
"""简单预估 Token 数量(按字符/4估算)"""
if not payload:
return 0
content = payload.get("messages", [])
total_chars = 0
for msg in content:
total_chars += len(str(msg.get("content", "")))
return total_chars // 4
四、日志与监控模块
完善的日志记录是问题排查和成本分析的基础。我们记录每次请求的完整生命周期。
import json
import time
from datetime import datetime
from typing import Optional, Dict
from dataclasses import dataclass, asdict
import threading
@dataclass
class APILogEntry:
"""API 调用日志条目"""
request_id: str
user_id: str
timestamp: str
endpoint: str
model: str
input_tokens: int
output_tokens: int
total_tokens: int
latency_ms: float
status_code: int
error: Optional[str]
cost_usd: float
provider: str = "holysheep"
class LoggingMiddleware:
"""结构化日志中间件"""
def __init__(self, es_client=None, redis_client=None):
self.es_client = es_client
self.redis_client = redis_client
self.log_buffer = []
self.buffer_size = 100
self.flush_interval = 5
self._start_flush_thread()
def _start_flush_thread(self):
"""启动后台刷新线程"""
def flush_loop():
while True:
time.sleep(self.flush_interval)
self._flush_buffer()
thread = threading.Thread(target=flush_loop, daemon=True)
thread.start()
def _flush_buffer(self):
"""批量写入日志"""
if not self.log_buffer:
return
logs = self.log_buffer[:]
self.log_buffer.clear()
# 写入 Elasticsearch 或其他存储
if self.es_client:
self.es_client.bulk_index(logs)
# 写入 Redis 用于实时查询
if self.redis_client:
pipe = self.redis_client.pipeline()
for log in logs:
pipe.lpush("api_logs", json.dumps(log))
pipe.ltrim("api_logs", 0, 9999) # 保留最近10000条
pipe.execute()
def log_request(self, entry: APILogEntry):
"""记录 API 调用"""
self.log_buffer.append(asdict(entry))
if len(self.log_buffer) >= self.buffer_size:
self._flush_buffer()
def get_cost_summary(self, user_id: str, days: int = 7) -> Dict:
"""获取用户成本汇总"""
# 简化实现,实际应查询数据库/ES
return {
"user_id": user_id,
"period": f"last_{days}_days",
"total_requests": 0,
"total_input_tokens": 0,
"total_output_tokens": 0,
"estimated_cost_usd": 0.0
}
五、HolySheheep API 集成与成本优化
将网关与 HolySheheep AI 集成,充分利用其独特优势:
- 汇率优势:¥1=$1 无损兑换,相比官方 ¥7.3=$1 可节省超过 85% 成本
- 国内直连:延迟 <50ms,无需翻墙
- 价格优势:DeepSeek V3.2 仅 $0.42/MTok,Gemini 2.5 Flash 仅 $2.50/MTok
import requests
from flask import Flask, request, g, jsonify
app = Flask(__name__)
初始化中间件
redis_client = redis.Redis(host='localhost', port=6379, db=0)
auth_mw = AuthMiddleware(redis_client)
rate_limit_mw = RateLimitMiddleware()
logging_mw = LoggingMiddleware(redis_client=redis_client)
@app.route("/v1/chat/completions", methods=["POST"])
@auth_mw.require_auth
@rate_limit_mw.enforce_rate_limit
def chat_completions():
"""Chat Completions 代理接口"""
request_id = request.headers.get("X-Request-ID", f"req_{int(time.time()*1000)}")
start_time = time.time()
payload = request.json
model = payload.get("model", "gpt-4o")
# 转发至 HolySheheep API
# 利用国内直连优势,延迟更低
upstream_url = "https://api.holysheep.ai/v1/chat/completions"
try:
response = requests.post(
upstream_url,
headers={
"Authorization": f"Bearer {g.api_key}",
"Content-Type": "application/json",
"X-Request-ID": request_id
},
json=payload,
timeout=request.timeout if hasattr(request, 'timeout') else 120,
stream=False
)
latency_ms = (time.time() - start_time) * 1000
result = response.json()
# 提取 Token 用量
usage = result.get("usage", {})
input_tokens = usage.get("prompt_tokens", 0)
output_tokens = usage.get("completion_tokens", 0)
total_tokens = usage.get("total_tokens", 0)
# 计算成本(基于 HolySheheep 价格表)
cost = calculate_cost(model, input_tokens, output_tokens)
# 记录日志
log_entry = APILogEntry(
request_id=request_id,
user_id=g.user_id,
timestamp=datetime.utcnow().isoformat(),
endpoint="/v1/chat/completions",
model=model,
input_tokens=input_tokens,
output_tokens=output_tokens,
total_tokens=total_tokens,
latency_ms=latency_ms,
status_code=response.status_code,
error=None,
cost_usd=cost
)
logging_mw.log_request(log_entry)
return jsonify(result)
except requests.exceptions.Timeout:
return jsonify({
"error": "Upstream request timeout",
"code": "TIMEOUT"
}), 504
except Exception as e:
return jsonify({
"error": str(e),
"code": "UPSTREAM_ERROR"
}), 502
def calculate_cost(model: str, input_tokens: int, output_tokens: int) -> float:
"""基于 HolySheheep 价格计算单次调用成本(USD)"""
# HolySheheep 2026 主流价格 (per 1M tokens)
prices = {
"gpt-4.1": {"input": 8.0, "output": 8.0},
"claude-sonnet-4.5": {"input": 15.0, "output": 15.0},
"gemini-2.5-flash": {"input": 2.50, "output": 2.50},
"deepseek-v3.2": {"input": 0.42, "output": 0.42},
# 更多模型价格可查询 HolyShehe