# 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) | 返回文档总览 |