vault backup: 2026-06-03 10:30:42

This commit is contained in:
2026-06-03 10:30:42 +08:00
parent 2e207dc8fb
commit b5d9e44f0b
16 changed files with 661 additions and 507 deletions
+45 -28
View File
@@ -1,19 +1,30 @@
# 03 - 任务队列 (Task Queue)
---
tags: [task-queue, plugin-architecture, memory-queue, rabbitmq, go, interface-pattern]
create time: 2026-06-03 10:10
---
# 03. 任务队列 (Task Queue)
## 概述
可插拔任务队列接口,支持 Memory 和 RabbitMQ 双实现,通过工厂模式一行切换,满足不同部署环境的需求。
> **一句话概括**:可插拔任务队列接口,支持 Memory 和 RabbitMQ 双实现,通过工厂模式一行切换。
## 架构设计
## 正文
### 架构设计
```mermaid
graph TB
subgraph Producer["生产者"]
HANDLER["Handler.Generate()"]
HANDLER["Handler.Generate"]
end
subgraph Interface["TaskQueue 接口"]
SUBMIT["Submit(ctx, msg)"]
CONSUME["Consume(ctx, handler)"]
CLOSE["Close()"]
subgraph Interface["TaskQueue接口"]
SUBMIT["Submitctx msg"]
CONSUME["Consumectx handler"]
CLOSE["Close"]
end
subgraph Memory["MemoryQueue"]
@@ -36,7 +47,7 @@ graph TB
RabbitMQ --- RMQ_PUB
```
## TaskQueue 接口
### TaskQueue 接口
```go
type TaskQueue interface {
@@ -52,7 +63,7 @@ type TaskQueue interface {
| `Consume` | 持续消费任务,直到 ctx 取消 | handler 返回错误时,内存队列丢弃,RabbitMQ NACK 重试 |
| `Close` | 关闭连接,释放资源 | 返回 `errors.Join` 聚合错误 |
## 工厂模式
### 工厂模式
通过配置驱动,一行切换队列实现:
@@ -76,7 +87,7 @@ func New(cfg config.TaskQueueConfig) (TaskQueue, error) {
| `"memory"` (默认) | `MemoryQueue` | 单机开发、演示环境 |
| `"rabbitmq"` | `RabbitMQQueue` | 多机生产部署 |
## TaskMessage 消息结构
### TaskMessage 消息结构
```go
type TaskMessage struct {
@@ -95,7 +106,7 @@ type TaskMessage struct {
- `RetryCount` 供 RabbitMQ 实现判断是否超过最大重试次数
- JSON 序列化,兼容内存队列和 RabbitMQ 两种传输
## MemoryQueue 实现
### MemoryQueue 实现
基于 Go channel 的内存队列,零外部依赖。
@@ -109,7 +120,7 @@ type MemoryQueue struct {
}
```
### Submit
#### Submit
```go
func (q *MemoryQueue) Submit(ctx context.Context, msg TaskMessage) error {
@@ -124,9 +135,11 @@ func (q *MemoryQueue) Submit(ctx context.Context, msg TaskMessage) error {
}
```
> :bulb: **阻塞语义**:MemoryQueue 的 Submit 是阻塞的——当 buffer 满时,调用方会阻塞直到有空位或 ctx 取消。这与 WorkerPool 的非阻塞拒绝形成对比。
> [!tip] 阻塞语义
>
> MemoryQueue 的 Submit 是阻塞的——当 buffer 满时,调用方会阻塞直到有空位或 ctx 取消。这与 WorkerPool 的非阻塞拒绝形成对比。
### Consume
#### Consume
```go
func (q *MemoryQueue) Consume(ctx context.Context, handler func(TaskMessage) error) error {
@@ -155,11 +168,13 @@ func (q *MemoryQueue) Consume(ctx context.Context, handler func(TaskMessage) err
| 背压 | 阻塞直到有空位 |
| 依赖 | 零外部依赖 |
> :warning: **可接受的任务丢失**:AI 生成任务可以重新提交,进程重启丢失排队中的任务是可接受的权衡。
> [!warning] 可接受的任务丢失
>
> AI 生成任务可以重新提交,进程重启丢失排队中的任务是可接受的权衡。但如果你的业务场景中 **任务不可重放**(比如支付指令),则必须选择 RabbitMQ 等持久化实现。
## RabbitMQQueue 实现
### RabbitMQQueue 实现
基于 AMQP 的持久化消息队列,支持手动 ACK 和重试。详见 [04-rabbitmq](04-rabbitmq.md)。
基于 AMQP 的持久化消息队列,支持手动 ACK 和重试。详见 [[04-RabbitMQ集成]]。
**RabbitMQQueue 特性**:
@@ -170,7 +185,7 @@ func (q *MemoryQueue) Consume(ctx context.Context, handler func(TaskMessage) err
| 背压 | 发布失败时返回错误(不阻塞) |
| 依赖 | 需要 RabbitMQ 服务 |
## 双实现对比
### 双实现对比
| 维度 | MemoryQueue | RabbitMQQueue |
|------|-------------|---------------|
@@ -182,7 +197,7 @@ func (q *MemoryQueue) Consume(ctx context.Context, handler func(TaskMessage) err
| **适用** | 开发/演示 | 生产环境 |
| **消息丢失** | 进程重启丢失 | 服务重启不丢失 |
## Consumer 桥接
### Consumer 桥接
Consumer 从 TaskQueue 消费消息,提交到 WorkerPool 执行,实现队列与并发控制的解耦:
@@ -201,12 +216,14 @@ func (c *Consumer) Start(ctx context.Context) error {
}
```
```
TaskQueue → Consumer → WorkerPool → Pipeline
全局排队 桥接 单机并发 业务逻辑
```mermaid
graph LR
TQ["TaskQueue全局排队"] --> CONSUMER["Consumer桥接"]
CONSUMER --> WP["WorkerPool单机并发"]
WP --> PIPELINE["Pipeline业务逻辑"]
```
## 三级降级策略
### 三级降级策略
Gen2D 在 `cmd/main.go` 中实现了三级降级链:
@@ -229,7 +246,7 @@ if taskQueue != nil {
}
```
## Metrics 指标
### Metrics 指标
| Prometheus 指标 | 类型 | Label | 说明 |
|-----------------|------|-------|------|
@@ -241,7 +258,7 @@ if taskQueue != nil {
## 关联文档
- [索引](00-index.md) — 文档导航与架构总览图
- [系统总览](01-system-overview.md) — 分层架构与依赖注入
- [协程池](02-worker-pool.md) — 有界并发与 per-user 限流
- [RabbitMQ 集成](04-rabbitmq.md) — 持久化消息与重试机制
- [[00-索引]] — 文档导航与架构总览图
- [[01-系统总览]] — 分层架构与依赖注入
- [[02-协程池]] — 有界并发与 per-user 限流
- [[04-RabbitMQ集成]] — 持久化消息与重试机制