共计 1930 个字符,预计需要花费 5 分钟才能阅读完成。
背景痛点
直接调用 ChatGPT 官方 API 存在几个明显问题:

- 地域限制 :部分国家 / 地区的 IP 会被 OpenAI 屏蔽
- 账号风控 :高频调用容易触发账号封禁
- 速率限制 :免费账号每分钟仅允许 3 次请求
- 延迟较高 :国内直连美国服务器延迟普遍在 300ms 以上
自建镜像站可以有效解决这些问题,同时还能实现请求聚合、缓存加速等额外优化。
技术选型
方案对比
- Nginx 反向代理
- 优势:资源占用低、配置灵活、支持 Lua 扩展
-
劣势:需要自行维护服务器
-
Cloudflare Workers
- 优势:无需管理基础设施、全球边缘节点
-
劣势:无法深度定制流量策略
-
OpenResty
- 优势:完整保留 Nginx 特性 + 内置 LuaJIT
- 劣势:学习曲线较陡
推荐组合 :OpenResty + Redis,适合需要精细流量控制的场景
核心实现
SSL 加密配置
-
申请免费证书(Let’s Encrypt 为例):
sudo certbot certonly --nginx -d yourdomain.com -
Nginx 配置示例:
server { listen 443 ssl; ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384'; }
JWT 验证实现
-
生成密钥对:
openssl genpkey -algorithm RSA -out private.key openssl rsa -pubout -in private.key -out public.key -
OpenResty 配置:
location /api { access_by_lua_block { local jwt = require "resty.jwt" local token = ngx.req.get_headers()["Authorization"] local jwt_obj = jwt:verify("your_public_key", token) if not jwt_obj["verified"] then ngx.exit(403) end } proxy_pass https://api.openai.com; }
IP 轮询策略
通过 Lua 脚本实现多 API 密钥轮换:
local redis = require "resty.redis"
local red = redis:new()
local keys = {"sk-xxx1", "sk-xxx2", "sk-xxx3"}
local idx = tonumber(red:get("key_idx")) or 1
local current_key = keys[idx]
red:set("key_idx", idx % #keys + 1)
ngx.req.set_header("Authorization", "Bearer"..current_key)
避坑指南
速率限制规避
- 每个 API 密钥设置独立计数器
- 当返回 429 状态码时自动切换备用密钥
- 使用漏桶算法控制请求速率
API 密钥保护
- 永远不要在前端暴露原始密钥
- 采用短期有效的 JWT 令牌
- 密钥存储在 Vault 或 KMS 中
监控告警
推荐 Prometheus+Alertmanager 组合:
1. 监控指标包括:
– 请求成功率
– 平均响应时间
– 密钥使用频次
2. 告警规则示例:
- alert: HighErrorRate
expr: rate(requests_failed[1m]) > 0.1
for: 5m
性能测试
测试环境:2 核 4G 云服务器,上海区域
| 方案 | 平均延迟 | QPS |
|---|---|---|
| 官方 API 直连 | 320ms | 12 |
| 香港镜像站 | 180ms | 35 |
| 新加坡镜像站 | 210ms | 28 |
安全加固
DDoS 防护
-
启用 Nginx 限流模块:
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s; -
配置 WAF 规则拦截恶意特征
数据脱敏
-
日志中过滤敏感字段:
log_format sanitized '$remote_addr - $sanitized_request'; -
使用 Lua 脚本实时脱敏:
local function sanitize(msg) return msg:gsub("sk-[A-Za-z0-9]+", "[REDACTED]") end
优化方向
可以考虑:
1. 将静态资源托管到 CDN
2. 在不同大区部署边缘节点
3. 实现请求预测式缓存
通过合理的架构设计,完全可以在免费额度内支持中小规模的使用需求。关键在于做好流量控制和监控,避免意外超出限额。
正文完
发表至: 未分类
近三天内
