- Remove old review reports (keep latest only) - Move docs/ to deploy/docs-backup/ - Move performance-testing/ to deploy/ - Clean up test output files - Organize root directory
12 KiB
12 KiB
Sub2API 模块分析报告:账户管理模块
1. 模块概述
1.1 模块定位
账户管理模块是 Sub2API 的上游资源管理核心,负责管理连接到 AI 服务提供商的账号(Account)。这些账号是系统转发请求的"上游凭证",包括 OAuth 授权账号、API Key 账号等。
1.2 核心职责
- 账号 CRUD:创建、读取、更新、删除上游账号
- 账号状态管理:监控账号健康、处理限流和过期
- 分组管理:将账号分组以实现资源隔离和配额控制
- 账号测试:验证账号有效性(TestConnection)
2. 代码结构分析
2.1 核心文件
| 文件路径 | 职责 | 代码行数 |
|---|---|---|
service/account.go |
账号实体定义和服务基础 | ~800 行 |
service/account_service.go |
账号管理核心逻辑 | ~1200 行 |
service/account_group.go |
分组管理服务 | ~500 行 |
service/account_usage_service.go |
账号用量监控 | ~400 行 |
service/account_expiry_service.go |
账号过期管理 | ~300 行 |
handler/admin/account_handler.go |
账号管理 API | ~1900 行 |
repository/account_repo.go |
账号数据访问层 | ~1800 行 |
2.2 数据模型
// ent/schema/account.go
type Account struct {
ID int64 // 主键
Platform string // 平台:anthropic/openai/gemini/antigravity/bedrock
Type string // 类型:oauth/apikey
Name string // 账号名称(显示用)
Credentials string // 加密凭证(JSON)
Extra string // 额外配置(JSON)
Status string // 状态:active/error/disabled/expired
GroupID int64 // 所属分组
RateMultiplier float64 // 计费倍率
MaxConcurrency int // 最大并发
BaseURL string // 自定义上游地址
CreatedAt time.Time
UpdatedAt time.Time
}
3. 功能详细分析
3.1 账号类型支持
| 平台 | 类型 | 认证方式 | 特性 |
|---|---|---|---|
| Anthropic | OAuth / API Key | Bearer Token | Claude 模型支持 |
| OpenAI | API Key | Bearer Token | ChatGPT、GPT 模型 |
| Google Gemini | API Key | Bearer Token | 多模态支持 |
| Antigravity | OAuth | 独立认证系统 | 独立配额 |
| AWS Bedrock | API Key | AWS 签名 v4 | Claude on Bedrock |
3.2 账号创建流程
// service/account_service.go - CreateAccount
func (s *AccountService) CreateAccount(ctx context.Context, req CreateAccountRequest) (*Account, error) {
// 1. 验证请求参数
if err := validateAccountRequest(req); err != nil {
return nil, err
}
// 2. 加密凭证
encryptedCreds, err := s.encryptCredentials(req.Credentials)
if err != nil {
return nil, err
}
// 3. 创建账号
account := &Account{
Platform: req.Platform,
Type: req.Type,
Name: req.Name,
Credentials: encryptedCreds,
GroupID: req.GroupID,
Status: StatusActive,
}
// 4. 保存到数据库
return s.accountRepo.Create(ctx, account)
}
3.3 账号验证 (TestConnection)
// service/account_test_service.go - TestAccount
func (s *AccountTestService) TestAccount(ctx context.Context, account *Account) (*TestResult, error) {
// 1. 构建测试请求
testReq := buildTestRequest(account)
// 2. 发送请求
resp, err := s.sendRequest(ctx, account, testReq)
if err != nil {
return &TestResult{
Success: false,
Error: err.Error(),
}, nil
}
// 3. 检查响应
if !isSuccessResponse(resp) {
return &TestResult{
Success: false,
StatusCode: resp.StatusCode,
Error: parseError(resp.Body),
}, nil
}
// 4. 解析响应(获取配额信息)
quota := parseQuotaInfo(resp.Body)
return &TestResult{
Success: true,
QuotaInfo: quota,
StatusCode: 200,
}, nil
}
验证端点:
| 平台 | 测试端点 | 验证内容 |
|---|---|---|
| Anthropic | /v1/messages |
基本连通性 + 配额 |
| OpenAI | /v1/models |
模型列表 |
| Gemini | /v1/models |
模型列表 |
| Antigravity | /v1/models |
模型列表 |
| Bedrock | /invocations |
基本连通性 |
3.4 账号状态管理
// 账号状态转换
const (
StatusActive = "active" // 正常可用
StatusError = "error" // 出错(临时)
StatusDisabled = "disabled" // 管理员禁用
StatusExpired = "expired" // 已过期
StatusRateLimited = "rate_limited" // 被限流
)
// 状态检查
func (a *Account) CanUse() bool {
return a.Status == StatusActive || a.Status == StatusRateLimited
}
状态变更触发:
- Active → Error:TestConnection 失败、请求返回 5xx
- Active → RateLimited:上游返回 429
- Active → Expired:检测到过期时间
- Any → Disabled:管理员手动操作
3.5 账号分组管理
// service/account_group.go
type Group struct {
ID int64
Name string
Platform string // 平台类型
Status string
RateMultiplier float64 // 计费倍率
MaxConcurrency int // 分组最大并发
Models []string // 允许的模型列表
IsExclusive bool // 独占模式(只能被单个用户使用)
}
分组特性:
- 按平台隔离:不同平台使用不同分组
- 模型限制:分组可限定可用模型
- 独占模式:某些分组只允许单个用户访问
- 计费倍率:不同分组可有不同计费策略
3.6 账号用量追踪
// service/account_usage_service.go
func (s *AccountUsageService) RecordUsage(ctx context.Context, accountID int64, tokens int, cost float64) error {
// 1. 更新内存统计
s.localStats.Add(accountID, tokens, cost)
// 2. 更新 Redis 统计
s.redisStats.Incr(accountID, tokens, cost)
// 3. 定期同步到数据库
if s.shouldSync(accountID) {
s.syncToDB(accountID)
}
return nil
}
// 获取当前负载
func (s *AccountUsageService) GetLoadFactor(accountID int64) float64 {
activeConns := s.GetActiveConnections(accountID)
maxConns := s.GetMaxConcurrency(accountID)
return float64(activeConns) / float64(maxConns)
}
4. 高级功能
4.1 账号预热
// service/account_intercept_warmup.go
// 新账号首次使用前进行预热请求
func WarmupAccount(account *Account) error {
// 发送轻量级请求建立连接
req := &Request{
Model: "claude-3-haiku-20240307", // 最小的模型
MaxTokens: 1,
}
resp, err := sendRequest(account, req)
if err != nil {
return err
}
// 预热后更新状态
account.Status = StatusActive
return nil
}
4.2 账号健康检查
// service/account_health_check.go
func (s *HealthCheckService) CheckAccount(accountID int64) {
account := s.getAccount(accountID)
// 检查最后活跃时间
if time.Since(account.LastUsedAt) > 24*time.Hour {
// 超过 24 小时未使用,发送探测请求
s.testAccount(account)
}
// 检查过期时间
if account.ExpiresAt != nil && time.Now().After(*account.ExpiresAt) {
s.updateStatus(accountID, StatusExpired)
}
}
4.3 账号配额重置
// service/account_quota_reset.go
func (s *QuotaResetService) ResetDailyQuota() {
// 每天 UTC 0 点重置
for _, account := range s.getAllAccounts() {
account.UsageToday = 0
account.UpdatedAt = time.Now()
s.accountRepo.Update(account)
}
}
5. 数据访问层
5.1 Repository 接口
// repository/account_repo.go
type AccountRepository interface {
Create(ctx context.Context, account *Account) (*Account, error)
GetByID(ctx context.Context, id int64) (*Account, error)
GetByGroupID(ctx context.Context, groupID int64) ([]*Account, error)
Update(ctx context.Context, account *Account) error
Delete(ctx context.Context, id int64) error
// 高级查询
GetAvailableAccounts(ctx context.Context, groupID int64) ([]*Account, error)
Search(ctx context.Context, filters AccountFilters) ([]*Account, error)
}
5.2 查询优化
// 常用查询优化
func (r *accountRepository) GetAvailableAccounts(ctx context.Context, groupID int64) ([]*Account, error) {
return r.client.Account.Query().
Where(
account.GroupID(groupID),
account.StatusEQ("active"),
account.DeletedAtIsNil(),
).
All(ctx)
}
6. 配置参数
6.1 账号配置(config.yaml)
account:
# 账号健康检查
health_check:
enabled: true
interval: 5m
timeout: 30s
# 账号预热
warmup:
enabled: true
model: "claude-3-haiku-20240307"
# 配额重置
quota_reset:
timezone: "UTC"
hour: 0
# 限流配置
rate_limit:
window: 60s
max_errors: 3
reset_after: 300s
6.2 环境变量
| 变量 | 说明 | 默认值 |
|---|---|---|
ACCOUNT_HEALTH_CHECK_ENABLED |
启用健康检查 | true |
ACCOUNT_WARMUP_ENABLED |
启用预热 | true |
ACCOUNT_MAX_CONCURRENCY |
默认最大并发 | 10 |
7. 修改和扩展指南
7.1 常见修改场景
场景 1:添加新的账号类型
// 1. 在 domain/constants.go 添加类型
const AccountTypeCustom = "custom"
// 2. 在 service/account.go 添加验证
func (a *Account) ValidateCustom() error {
// 自定义验证逻辑
}
// 3. 在 handler 中添加创建接口
router.POST("/accounts/custom", createCustomAccount)
场景 2:调整账号选择策略
// service/account_service.go - SelectAccount
func (s *AccountService) SelectAccount(ctx context.Context, groupID int64, model string) (*Account, error) {
// 调整选择逻辑
accounts := s.getAvailableAccounts(groupID)
// 按负载排序
sort.Slice(accounts, func(i, j int) bool {
return accounts[i].LoadFactor < accounts[j].LoadFactor
})
return accounts[0], nil
}
场景 3:修改限流行为
// service/account_service.go - HandleRateLimit
func (s *AccountService) HandleRateLimit(accountID int64, resetAfter time.Duration) error {
// 修改限流持续时间
account, _ := s.GetByID(accountID)
account.Status = StatusRateLimited
account.RateLimitedAt = time.Now()
account.RateLimitResetAt = time.Now().Add(resetAfter * 2) // 倍增
return s.Update(account)
}
7.2 注意事项
- 凭证安全:账号凭证必须加密存储,密钥独立管理
- 并发安全:账号选择需要考虑并发场景
- 状态一致性:账号状态变更需要同步到缓存
8. 测试覆盖
8.1 单元测试
| 测试文件 | 覆盖范围 |
|---|---|
account_service_test.go |
账号 CRUD |
account_load_factor_test.go |
负载计算 |
account_expiry_service_test.go |
过期处理 |
account_test_service_openai_test.go |
OpenAI 测试 |
8.2 集成测试
| 测试文件 | 场景 |
|---|---|
e2e_gateway_test.go |
账号选择和请求转发 |
9. 监控与运维
9.1 关键指标
| 指标 | 告警阈值 | 说明 |
|---|---|---|
account_error_count |
> 10 | 账号错误数 |
account_rate_limited |
> 20% | 账号限流比例 |
account_expired |
> 5% | 账号过期比例 |
account_test_success_rate |
< 90% | 测试成功率 |
9.2 运维任务
| 任务 | 频率 | 说明 |
|---|---|---|
| 健康检查 | 5 分钟 | 检查账号可用性 |
| 配额重置 | 每天 | 重置每日用量 |
| 过期检查 | 每天 | 检查账号过期时间 |
| 统计同步 | 每小时 | 同步用量到数据库 |
10. 总结
账户管理模块特点:
- 多平台支持:统一接口管理多种 AI 服务账号
- 状态自动化:自动处理限流、过期等状态
- 分组隔离:通过分组实现资源隔离和配额控制
- 健康监控:持续的账号健康检查和预热
潜在改进点:
- 账号测试可以更全面(模拟实际请求)
- 支持更多账号配置选项(代理、超时等)
修改建议:
- 账号类型扩展相对简单,风险较低
- 状态管理逻辑修改需充分测试
文档版本:1.0 最后更新:2025-01 分析基于:Sub2API v0.1.104