vault backup: 2026-06-03 10:22:41

This commit is contained in:
2026-06-03 10:22:41 +08:00
parent 6f8363fd3c
commit 2e207dc8fb
16 changed files with 0 additions and 0 deletions
+183
View File
@@ -0,0 +1,183 @@
# 12. 三级降级策略
> **一句话概括**:Generate handler 实现三级降级 — TaskQueue -> WorkerPool -> Legacy FIFO,宁可降级也不拒绝服务。
---
## 降级链总览
```mermaid
flowchart TD
R["HTTP Request\nPOST /api/v1/generate"] --> A{"TaskQueue\n可用?"}
A -->|"Submit 成功"| S1["200 OK\ntaskId 返回"]
A -->|"Submit 失败"| B{"WorkerPool\n可用?"}
B -->|"Submit 成功"| S2["200 OK\ntaskId 返回"]
B -->|"ErrPoolFull"| E2["503 Service\nUnavailable"]
B -->|"ErrUserLimit"| E3["429 Too Many\nRequests"]
B -->|"Pool 不可用"| C{"Legacy FIFO\nQueue 可用?"}
C -->|"Enqueue 成功"| S3["200 OK\ntaskId 返回"]
C -->|"Queue 不可用"| E4["500 Internal\nServer Error"]
style A fill:#4caf50,stroke:#333,color:#fff
style B fill:#ff9800,stroke:#333,color:#fff
style C fill:#f44336,stroke:#333,color:#fff
style S1 fill:#8bc34a,stroke:#333,color:#fff
style S2 fill:#8bc34a,stroke:#333,color:#fff
style S3 fill:#8bc34a,stroke:#333,color:#fff
```
---
## 三级详解
### 第一级:TaskQueue(优先路径)
| 属性 | 说明 |
|------|------|
| **组件** | `taskqueue.TaskQueue` 接口(Memory / RabbitMQ) |
| **特点** | 支持持久化、分布式、消息确认 |
| **提交** | `taskQueue.Submit(ctx, msg)` |
| **失败时** | 返回 HTTP 500,标记任务为 `failed` |
```go
// handler/generate.go — 第一级
if taskQueue != nil {
msg := taskqueue.TaskMessage{...}
if err := taskQueue.Submit(ctx, msg); err != nil {
c.JSON(500, "提交任务失败")
return
}
c.JSON(200, taskId)
return // 成功,不再降级
}
```
### 第二级:WorkerPool(有界并发)
| 属性 | 说明 |
|------|------|
| **组件** | `workerpool.Pool` |
| **特点** | 有界队列 + per-user 并发限制 |
| **提交** | `workerPool.Submit(task)` |
| **失败类型** | `ErrPoolFull` -> 503 / `ErrUserLimitReached` -> 429 |
```go
// handler/generate.go — 第二级
if workerPool != nil {
err := workerPool.Submit(workerpool.Task{...})
switch {
case errors.Is(err, workerpool.ErrPoolFull):
c.JSON(503, "系统繁忙,请稍后重试")
case errors.Is(err, workerpool.ErrUserLimitReached):
c.JSON(429, "您的生成任务已达上限")
default:
c.JSON(500, "提交任务失败")
}
return
}
```
### 第三级:Legacy FIFO(最后保底)
| 属性 | 说明 |
|------|------|
| **组件** | `service.TaskQueue`(串行 FIFO 队列) |
| **特点** | 零配置、串行执行、无并发控制 |
| **用途** | 兜底,确保系统在任何配置下都能运行 |
```go
// handler/generate.go — 第三级
if generateQueue != nil {
generateQueue.Enqueue(&service.TaskJob{...})
}
c.JSON(200, taskId)
```
---
## HTTP 状态码映射
```mermaid
flowchart LR
subgraph "降级路径"
TQ["TaskQueue"]
WP["WorkerPool"]
LF["Legacy FIFO"]
end
subgraph "HTTP 响应"
E200["200 OK\n任务已接受"]
E429["429 Too Many Requests\n用户限流"]
E500["500 Internal Server Error\n系统错误"]
E503["503 Service Unavailable\n系统繁忙"]
end
TQ -->|"成功"| E200
TQ -->|"失败"| E500
WP -->|"成功"| E200
WP -->|"队列满"| E503
WP -->|"用户限流"| E429
LF -->|"成功"| E200
LF -->|"不可用"| E500
```
| 状态码 | 含义 | 触发条件 |
|--------|------|----------|
| `200` | 任务已接受 | 任意一级提交成功 |
| `429` | 用户限流 | WorkerPool 用户并发达到上限 |
| `500` | 系统内部错误 | TaskQueue 提交失败 / 所有级别不可用 |
| `503` | 服务暂不可用 | WorkerPool 队列已满 |
---
## 为什么需要三级?
```mermaid
flowchart TB
subgraph "第一级:分布式能力"
TQ["TaskQueue\n持久化 + 消息确认\n支持 RabbitMQ 横向扩展"]
end
subgraph "第二级:并发控制"
WP["WorkerPool\n有界队列背压\nper-user 限流保护"]
end
subgraph "第三级:可用性兜底"
LF["Legacy FIFO\n零依赖、零配置\n确保始终可运行"]
end
TQ -->|"不可用时降级到"| WP
WP -->|"不可用时降级到"| LF
```
| 级别 | 核心价值 | 典型场景 |
|------|----------|----------|
| TaskQueue | 分布式 + 持久化 | 生产环境,多实例部署 |
| WorkerPool | 并发控制 + 背压 | 单机部署,需要限制资源 |
| Legacy FIFO | 可用性兜底 | 开发/测试环境,或队列组件故障 |
---
## 设计哲学
> **宁可降级,也不能拒绝服务。**
三级降级的核心思想是**渐进式降级**:
1. **功能完整** — TaskQueue 提供持久化、重试、死信等高级特性
2. **性能可控** — WorkerPool 提供有界并发和用户隔离
3. **始终可用** — Legacy FIFO 确保在任何配置下都能接收任务
每一级降级都意味着功能的减少,但服务的可用性始终得到保障。前端收到 `200 OK` 后,通过 SSE 或轮询获取任务进度,对用户而言体验一致。
---
## 关联文档
| 文档 | 关系 |
|------|------|
| [11 - Consumer-Producer 桥接](11-consumer-producer.md) | Consumer 连接 TaskQueue 和 WorkerPool |
| [02 - 协程池](02-worker-pool.md) | WorkerPool 的背压和限流机制 |
| [03 - 任务队列](03-task-queue.md) | TaskQueue 接口的可插拔设计 |
| [00 - 索引](00-index.md) | 返回文档总览 |