共计 2453 个字符,预计需要花费 7 分钟才能阅读完成。
背景痛点
在直接调用第三方 AI 服务 API 时,开发者常遇到以下几个痛点:

- IP 限制问题 :许多 AI 服务提供商对调用 IP 有严格限制,导致团队协作时频繁触发封禁
- 配额管理复杂 :Token 额度分散在不同账户,难以统一管理和监控使用情况
- 安全风险 :Token 硬编码在客户端或配置文件中,存在泄露风险
- 维护成本高 :Token 过期需要手动更换,影响服务连续性
架构设计
我们对比了两种常见方案:
- 纯反向代理模式
- 优点:配置简单,性能损耗小
-
缺点:无法实现细粒度的访问控制
-
API 网关模式
- 优点:支持鉴权、限流等高级功能
- 缺点:系统复杂度高
最终采用混合架构:
graph TD
Client --> Nginx(流量分发)
Nginx --> | 静态资源 | CDN
Nginx --> |API 请求 | GoService(业务逻辑)
GoService --> Redis(Token 池)
GoService --> ThirdAPI(第三方 AI 服务)
核心实现
JWT 验证中间件
func AuthMiddleware(next http.Handler) http.Handler {return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {tokenString := r.Header.Get("Authorization")
if tokenString == "" {log.Println("Missing auth header")
w.WriteHeader(http.StatusUnauthorized)
return
}
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {return nil, fmt.Errorf("unexpected signing method")
}
return []byte(os.Getenv("JWT_SECRET")), nil
})
if err != nil || !token.Valid {log.Printf("Invalid token: %v", err)
w.WriteHeader(http.StatusForbidden)
return
}
next.ServeHTTP(w, r)
})
}
Redis Token 池实现
func GetAvailableToken() (string, error) {ctx := context.Background()
client := redis.NewClient(&redis.Options{
Addr: "redis:6379",
Password: "",
})
// 使用 LPOP 获取 Token 并立即 RPUSH 到队尾
token, err := client.LPop(ctx, "token_pool").Result()
if err != nil {return "", fmt.Errorf("get token error: %v", err)
}
if err := client.RPush(ctx, "token_pool", token).Err(); err != nil {log.Printf("Warning: token recycle failed: %v", err)
}
return token, nil
}
性能优化
通过 Apache Bench 压测对比(并发 100 请求 1000 次):
| 方案 | 平均延迟 | 吞吐量 |
|---|---|---|
| 直连 API | 320ms | 312rps |
| 中转服务 | 350ms | 285rps |
| 中转 + 连接复用 | 325ms | 305rps |
连接复用关键代码:
var transport = &http.Transport{
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
}
client := &http.Client{Transport: transport}
避坑指南
处理 Rate Limit
- 实现指数退避重试:
func callWithRetry(apiCall func() error, maxRetries int) error {
backoff := 1 * time.Second
for i := 0; i < maxRetries; i++ {err := apiCall()
if err == nil {return nil}
if isRateLimitError(err) {time.Sleep(backoff)
backoff *= 2
continue
}
return err
}
return fmt.Errorf("max retries exceeded")
}
防范时序攻击
使用恒定时间比较算法:
func safeCompare(a, b string) bool {if len(a) != len(b) {return false}
var result byte
for i := 0; i < len(a); i++ {result |= a[i] ^ b[i]
}
return result == 0
}
扩展思考
请求审计实现方案
- 在中间件中记录请求日志
- 使用 ELK 栈存储和分析日志
- 关键字段:时间戳、用户 ID、API 端点、Token 使用量
计费系统设计
- 基于 Redis 的计数器实现配额管理
- 定时任务同步使用数据到数据库
- 余额不足时发送预警通知
实验环境
version: '3'
services:
proxy:
build: .
ports:
- "8080:8080"
depends_on:
- redis
redis:
image: redis:alpine
ports:
- "6379:6379"
volumes:
- redis_data:/data
volumes:
redis_data:
启动命令:docker-compose up --build
总结
通过搭建 Token 中转服务,我们实现了:
1. 统一入口管理多个 AI 服务账号
2. 自动化的 Token 轮换机制
3. 细粒度的访问控制和审计能力
后续可以结合服务网格技术,实现更灵活的流量治理策略。
正文完
