Files
easyai-ai-gateway/docs/server-main-integration.md
T
wangbo 810dcfeee6 perf(storage): 极简化任务历史并增加保留治理
停止持久化 provider 原始响应、兼容响应快照、attempt/event/outbox 重复 JSON,并由标准任务结果动态生成 Kling/Keling/Volces 兼容响应。

增加事件去重与预算、极简 callback 投递、7/30 天分批清理、安全删除条件、并发迁移索引及可实际恢复的任务域排除备份。历史清理默认关闭,待兼容协议和异步恢复在线验证后单独启用。

验证:Go 全量测试与 go vet、PostgreSQL 18 集成与实际备份恢复、迁移安全测试、bash -n、ShellCheck、Compose 配置和人工发布脚本测试均通过。
2026-07-24 18:23:22 +08:00

258 lines
7.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# server-main 对接清单
## 1. 需要在 server-main 增加的内部接口
### 1.1 API Key 校验
```http
POST /internal/platform/auth/verify-api-key
Authorization: Bearer ${SERVER_MAIN_INTERNAL_TOKEN}
Content-Type: application/json
{ "apiKey": "sk-..." }
```
返回:
```json
{
"sub": "user-id",
"username": "demo",
"role": ["user"],
"tenantId": "tenant-id",
"gatewayTenantId": "optional-gateway-tenant-id",
"tenantKey": "team-a",
"source": "server-main",
"gatewayUserId": "optional-gateway-user-id",
"userGroupId": "optional-primary-group-id",
"userGroupKey": "pro",
"userGroupKeys": ["pro", "image-plus"],
"apiKeyId": "key-id",
"apiKeySecret": "sk-...",
"apiKeyName": "production-key"
}
```
### 1.2 文件上传
```http
POST /api/v1/files/upload
Authorization: Bearer ${USER_JWT_OR_SK}
Content-Type: multipart/form-data
file=@result.png
```
AI Gateway 不维护独立 OSS 配置,也不向 `server-main` 申请预签名。需要上传本地中间产物、provider 临时 URL 转存、base64 解码结果时,统一组装 multipart 请求调用主服务开放上传接口,并记录主服务返回的 file id / URL / object key。
### 1.3 租户同步
AI Gateway 在独立模式下自己维护租户;接入 `server-main` 时保存主服务租户/组织同步副本,用于任务隔离、平台可见性、租户级限流和审计。
建议新增同步接口:
```http
POST /internal/platform/tenants/sync
Authorization: Bearer ${SERVER_MAIN_INTERNAL_TOKEN}
Content-Type: application/json
Idempotency-Key: tenant:${source}:${externalTenantId}:${version}
```
请求体:
```json
{
"source": "server-main",
"externalTenantId": "tenant-id",
"tenantKey": "team-a",
"name": "Team A",
"status": "active",
"planKey": "pro",
"rateLimitPolicy": {
"rules": [
{ "metric": "rpm", "limit": 500, "windowSeconds": 60 },
{ "metric": "concurrent", "limit": 20, "leaseTtlSeconds": 900 }
]
},
"sourceUpdatedAt": "2026-05-09T12:00:00Z"
}
```
要求:
- Gateway 使用 `source + externalTenantId` 幂等 upsert 到 `gateway_tenants`
- 租户禁用后,新任务拒绝入队;已运行任务按任务策略快照继续或由管理员取消。
- 用户同步必须带可映射的 `tenantId` / `tenantKey`,使任务、用户、用户组、限流和平台可见性都能落到同一租户上下文。
### 1.4 用户同步
AI Gateway 需要在独立模式下自己维护用户,在接入 `server-main` 时保存主服务用户的同步副本。同步副本只用于模型调用策略、审计、任务归属和用户组解析,不承接主服务余额、订单、充值流水。
建议新增同步接口:
```http
POST /internal/platform/users/sync
Authorization: Bearer ${SERVER_MAIN_INTERNAL_TOKEN}
Content-Type: application/json
Idempotency-Key: user:${source}:${externalUserId}:${version}
```
请求体:
```json
{
"source": "server-main",
"externalUserId": "user-id",
"username": "demo",
"displayName": "Demo User",
"email": "demo@example.com",
"tenantId": "tenant-id",
"tenantKey": "team-a",
"roles": ["user"],
"status": "active",
"sourceUpdatedAt": "2026-05-09T12:00:00Z",
"userGroupKeys": ["pro", "image-plus"]
}
```
要求:
- Gateway 使用 `source + externalUserId` 幂等 upsert 到 `gateway_users`
- `status=disabled/locked/deleted` 后,Gateway 应拒绝创建新任务;已运行任务按任务策略快照继续或由管理员取消。
- 用户角色以主服务返回为准,但 Gateway 可以叠加本地管理角色,二者需要在 `auth_profile``metadata` 里可审计。
- 用户组关系可以随用户同步一起带,也可以通过用户组同步接口单独维护,最终都落到 `gateway_user_group_memberships`
### 1.5 用户组与折扣策略同步
用户组是跨服务策略:Gateway 需要按用户组执行模型调用折扣、TPM/RPM/并发、队列优先级;`server-main` 需要按用户组执行充值折扣、资源包赠送、余额流水。两边必须保持同一个 `groupKey`
建议新增同步接口:
```http
POST /internal/platform/user-groups/sync
Authorization: Bearer ${SERVER_MAIN_INTERNAL_TOKEN}
Content-Type: application/json
Idempotency-Key: ${groupKey}:${version}
```
请求体:
```json
{
"groupKey": "enterprise",
"name": "企业组",
"rechargeDiscountPolicy": {
"type": "tiered_bonus",
"tiers": [{ "minAmount": 1000, "bonusRatio": 0.12 }]
},
"billingDiscountPolicy": {
"defaultDiscountFactor": 0.9
},
"rateLimitPolicy": {
"rules": [
{ "metric": "rpm", "limit": 1200, "windowSeconds": 60 },
{ "metric": "concurrent", "limit": 50, "leaseTtlSeconds": 900 }
]
},
"memberships": [
{ "principalType": "user", "principalId": "user-id" },
{ "principalType": "tenant", "principalId": "tenant-id" }
]
}
```
要求:
- `server-main` 是充值、余额和订单事实源,负责执行 `rechargeDiscountPolicy`
- Gateway 是模型执行事实源,负责执行 `billingDiscountPolicy``rateLimitPolicy`、队列和并发策略。
- 用户登录 / API Key 校验返回 claim 时,建议带上命中的 `userGroupKey` / `userGroupId`;Gateway 也可以根据同步缓存二次解析。
### 1.6 任务进度回调到 server-main
AI Gateway 不直接替换原业务前端 WebSocket 通道。Gateway 仅在真实任务状态变化时写入本地事件表和 callback outbox,再回调给 `server-main`,由 `server-main` 内部推送流程复用原 WebSocket 网关推送给业务前端。
```http
POST /internal/platform/task-progress-callbacks
Authorization: Bearer ${SERVER_MAIN_INTERNAL_TOKEN}
Content-Type: application/json
Idempotency-Key: ${taskId}:${seq}
X-EasyAI-Event-Type: task.completed
```
请求体:
```json
{
"taskId": "gateway-task-id",
"seq": 3,
"eventType": "task.completed",
"status": "succeeded",
"createdAt": "2026-05-09T12:00:00Z"
}
```
`server-main` 处理要求:
- 使用 `Idempotency-Key``taskId + seq` 幂等去重。
- 根据 `taskId` 定位原业务频道;需要完整结果时调用 task detail。
- 复用现有 WebSocket 网关事件格式推给前端,尽量不改业务前端订阅协议。
- 只负责推送与必要状态同步,不重新执行任务、不重新计算计费。
Gateway 侧配置:
```env
TASK_PROGRESS_CALLBACK_ENABLED=true
TASK_PROGRESS_CALLBACK_URL=http://easyai-server-main:3000/internal/platform/task-progress-callbacks
TASK_PROGRESS_CALLBACK_TIMEOUT_MS=5000
TASK_PROGRESS_CALLBACK_MAX_ATTEMPTS=10
```
### 1.7 结算事件
```http
POST /internal/platform/settlements
Authorization: Bearer ${SERVER_MAIN_INTERNAL_TOKEN}
Content-Type: application/json
Idempotency-Key: ${eventId}
```
结算事件中的 `billings` 由 AI Gateway 根据基准模型库、平台折扣、平台模型覆盖后的 effective pricing 计算。`server-main` 仍负责余额、资源包、账单锁和消费流水,不重新推导模型价格,只按幂等事件扣费。
## 2. server-main OpenaiService 薄门面
保留现有对内方法签名,内部新增 `AiGatewayClient`
- `createChatCompletion`
- `generateImage`
- `editImage`
- `generateVideo`
- `createEmbedding`
- `estimateBilling`
切流开关:
```env
AI_GATEWAY_ENABLED=true
AI_GATEWAY_BASE_URL=http://easyai-ai-gateway:8088
AI_GATEWAY_INTERNAL_TOKEN=change-me
AI_GATEWAY_TASK_PROGRESS_CALLBACK_ENABLED=true
```
## 3. 迁移期双写与比对
高风险接口可短期 shadow
1. 主路径仍走旧实现。
2. 异步把同一请求投递到 Gateway dry-run。
3. 比对候选平台、TPM/RPM/并发限流决策、预估扣费、参数预处理结果。
4. 结果稳定后切主路径。
## 4. 不迁移项
- `refresh_token` 签发和刷新。
- 用户余额查询。
- `server-main` 用户 API Key 的创建、撤销、列表。Gateway 独立模式会维护自己的本地 API Key。
- `server-main` 账单锁、扣费流水。Gateway 独立模式会维护自己的钱包账户、充值订单和钱包流水。
- OSS/COS/S3 上传配置和实际文件落库。
- 对话与绘图历史最终落库。