关于 using-message-queues
using-message-queues 是面向开发者的消息队列与事件驱动架构指南,帮助按场景选择代理,并实现后台任务、事件流和复杂工作流。
主要功能
- 01按场景选择消息代理
- 02后台任务处理模式
- 03事件流与日志聚合
- 04死信队列和幂等处理
- 05队列状态的 SSE 更新
适用场景
- 01将耗时操作移出 HTTP 请求
- 02处理邮件发送或图像调整等后台任务
- 03构建订单处理等多步骤工作流
- 04将事件流用于分析管道
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ ancoleman/ ai-design-components --skill using-message-queues安装后在 Claude Code 中输入/using-message-queues确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
outputs.yamlexamples/bullmq-webhook-processor/README.mdexamples/celery-image-processing/README.mdexamples/kafka-python/consumer.pyproducer.pyREADME.mdexamples/temporal-order-processing/activities.pyworkflow.pyexamples/temporal-order-saga/README.mdreferences/bullmq.mdcelery.mdevent-patterns.mdkafka.mdnats.mdrabbitmq.mdredis-streams.mdtemporal-workflows.mdscripts/kafka_producer_consumer.pyvalidate_message_schema.py详细介绍
消息队列
为事件驱动架构、后台任务处理和服务解耦实现异步通信模式。
何时使用此技能
在以下情况下使用消息队列:
- 长时间运行的操作会阻塞 HTTP 请求(报告生成、视频处理)
- 需要服务解耦(微服务、事件驱动架构)
- 需要可靠投递(支付处理、订单履约)
- 用于分析的事件流(日志聚合、指标管道)
- 复杂流程的工作流编排(多步骤 Saga、人工介入)
- 后台任务处理(发送邮件、调整图像大小)
消息代理选择决策树
根据主要需求选择消息代理:
事件流 / 日志聚合
→ Apache Kafka
- 吞吐量:500K-1M msg/s
- 重放事件(事件溯源)
- 精确一次语义
- 长期保留
- 用途:分析管道、CQRS、事件溯源
简单的后台任务
→ 任务队列
- Python → Celery + Redis
- TypeScript → BullMQ + Redis
- Go → Asynq + Redis
- 用途:发送邮件、生成报告、Webhooks
复杂工作流 / Saga
→ Temporal
- 持久化执行(重启后仍可继续)
- 支持 Saga 模式
- 人工介入工作流
- 用途:订单处理、AI Agent 编排
请求-响应 / RPC 模式
→ NATS
- 内置请求-响应
- 亚毫秒延迟
- 云原生、运维简单
- 用途:微服务 RPC、IoT 命令与控制
复杂消息路由
→ RabbitMQ
- 交换机(direct、topic、fanout、headers)
- 死信交换机
- 消息 TTL、优先级
- 用途:多消费者模式、发布/订阅
已在使用 Redis
→ Redis Streams
- 无需新增基础设施
- 简单的消费者组
- 中等吞吐量(100K+ msg/s)
- 用途:通知队列、简单任务队列
性能对比
| 消息代理 | 吞吐量 | 延迟(p99) | 最适合 |
|---|---|---|---|
| Kafka | 500K-1M msg/s | 10-50ms | 事件流 |
| NATS JetStream | 200K-400K msg/s | 亚毫秒至 5ms | 云原生微服务 |
| RabbitMQ | 50K-100K msg/s | 5-20ms | 任务队列、复杂路由 |
| Redis Streams | 100K+ msg/s | 亚毫秒 | 简单队列、缓存 |
快速入门示例
Kafka 生产者/消费者(Python)
查看 examples/kafka-python/ 获取可运行代码。
from confluent_kafka import Producer, Consumer
# Producer
producer = Producer({'bootstrap.servers': 'localhost:9092'})
producer.produce('orders', key='order_123', value='{"status": "created"}')
producer.flush()
# Consumer
consumer = Consumer({
'bootstrap.servers': 'localhost:9092',
'group.id': 'order-processors',
'auto.offset.reset': 'earliest'
})
consumer.subscribe(['orders'])
while True:
msg = consumer.poll(1.0)
if msg is not None:
process_order(msg.value())
Celery 后台任务(Python)
查看 examples/celery-image-processing/ 获取完整实现。
from celery import Celery
app = Celery('tasks', broker='redis://localhost:6379')
@app.task(bind=True, max_retries=3)
def process_image(self, image_url: str):
try:
result = expensive_image_processing(image_url)
return result
except RecoverableError as e:
raise self.retry(exc=e, countdown=60)
BullMQ 任务处理(TypeScript)
查看 examples/bullmq-webhook-processor/ 获取完整实现。
import { Queue, Worker } from 'bullmq'
const queue = new Queue('webhooks', {
connection: { host: 'localhost', port: 6379 }
})
// Enqueue job
await queue.add('send-webhook', {
url: 'https://example.com/webhook',
payload: { event: 'order.created' }
})
// Process jobs
const worker = new Worker('webhooks', async job => {
await fetch(job.data.url, {
method: 'POST',
body: JSON.stringify(job.data.payload)
})
}, { connection: { host: 'localhost', port: 6379 } })
Temporal 工作流编排
查看 examples/temporal-order-saga/ 获取 Saga 模式实现。
from temporalio import workflow, activity
from datetime import timedelta
@workflow.defn
class OrderSagaWorkflow:
@workflow.run
async def run(self, order_id: str) -> str:
# Step 1: Reserve inventory
inventory_id = await workflow.execute_activity(
reserve_inventory,
order_id,
start_to_close_timeout=timedelta(seconds=10),
)
# Step 2: Charge payment
payment_id = await workflow.execute_activity(
charge_payment,
order_id,
start_to_close_timeout=timedelta(seconds=30),
)
return f"Order {order_id} completed"
核心模式
事件命名约定
使用:Domain.Entity.Action.Version
示例:
order.created.v1user.profile.updated.v2payment.failed.v1
事件架构结构
{
"event_type": "order.created.v2",
"event_id": "uuid-here",
"timestamp": "2025-12-02T10:00:00Z",
"version": "2.0",
"data": {
"order_id": "ord_123",
"customer_id": "cus_456"
},
"metadata": {
"producer": "order-service",
"trace_id": "abc123",
"correlation_id": "xyz789"
}
}
死信队列模式
达到最大重试次数后,将失败消息路由到死信队列(DLQ):
@app.task(bind=True, max_retries=3)
def process_order(self, order_id: str):
try:
result = perform_processing(order_id)
return result
except UnrecoverableError as e:
send_to_dlq(order_id, str(e))
raise Reject(e, requeue=False)
精确一次处理的幂等性
@app.post("/process")
async def process_payment(
payment_data: dict,
idempotency_key: str = Header(None)
):
# Check if already processed
cached_result = redis_client.get(f"idempotency:{idempotency_key}")
if cached_result:
return {"status": "already_processed"}
result = process_payment_logic(payment_data)
redis_client.setex(f"idempotency:{idempotency_key}", 86400, result)
return {"status": "processed", "result": result}
前端集成
通过 SSE 更新任务状态
# FastAPI endpoint for real-time job status
@app.get("/status/{task_id}")
async def task_status_stream(task_id: str):
async def event_generator():
while True:
task = celery_app.AsyncResult(task_id)
if task.state == 'PROGRESS':
yield {"event": "progress", "data": task.info.get('progress', 0)}
elif task.state == 'SUCCESS':
yield {"event": "complete", "data": task.result}
break
await asyncio.sleep(0.5)
return EventSourceResponse(event_generator())
React 组件
export function JobStatus({ jobId }: { jobId: string }) {
const [progress, setProgress] = useState(0)
useEffect(() => {
const eventSource = new EventSource(`/api/status/${jobId}`)
eventSource.addEventListener('progress', (e) => {
setProgress(JSON.parse(e.data))
})
eventSource.addEventListener('complete', (e) => {
toast({ title: 'Job complete', description: JSON.parse(e.data) })
eventSource.close()
})
return () => eventSource.close()
}, [jobId])
return <ProgressBar value={progress} />
}
详细指南
如需完整文档,请参阅参考文件:
消息代理专属指南
- Kafka:参阅
references/kafka.md,了解分区、消费者组和精确一次语义 - RabbitMQ:参阅
references/rabbitmq.md,了解交换机、绑定和路由模式 - NATS:参阅
references/nats.md,了解 JetStream 和请求-响应模式 - Redis Streams:参阅
references/redis-streams.md,了解消费者组和确认机制
任务队列指南
- Celery:参阅
references/celery.md,了解周期性任务、canvas(工作流)和监控 - BullMQ:参阅
references/bullmq.md,了解任务优先级、流程和 Bull Board 监控 - Temporal:参阅
references/temporal-workflows.md,了解 Saga 模式、信号和查询
模式指南
- 事件模式:请参阅
references/event-patterns.md,了解事件溯源、CQRS 和 outbox 模式
应避免的常见反模式
1. 为长时间运行的操作使用同步 API
# ❌ BAD: Blocks request thread
@app.post("/generate-report")
def generate_report(user_id: str):
report = expensive_computation(user_id) # 5 minutes!
return report
# ✅ GOOD: Enqueue background job
@app.post("/generate-report")
async def generate_report(user_id: str):
task = generate_report_task.delay(user_id)
return {"task_id": task.id}
2. 非幂等消费者
# ❌ BAD: Processes duplicates
@app.task
def send_email(email: str):
send_email_service(email) # Sends twice if retried!
# ✅ GOOD: Idempotent with deduplication
@app.task
def send_email(email: str, idempotency_key: str):
if redis.exists(f"sent:{idempotency_key}"):
return "already_sent"
send_email_service(email)
redis.setex(f"sent:{idempotency_key}", 86400, "1")
3. 忽略死信队列
# ❌ BAD: Failed messages lost forever
@app.task(max_retries=3)
def risky_task(data):
process(data) # If all retries fail, data disappears
# ✅ GOOD: DLQ for manual inspection
@app.task(max_retries=3)
def risky_task(data):
try:
process(data)
except Exception as e:
if self.request.retries >= 3:
send_to_dlq(data, str(e))
raise
4. 使用 Kafka 实现请求-响应
# ❌ BAD: Kafka is not designed for RPC
def get_user_profile(user_id: str):
kafka_producer.send("user_requests", {"user_id": user_id})
# How to correlate response? Kafka is asynchronous!
# ✅ GOOD: Use NATS request-reply or HTTP/gRPC
response = await nats.request("user.profile", user_id.encode())
库推荐
Context7 调研
Confluent Kafka(Python)
- Context7 ID:
/confluentinc/confluent-kafka-python - 信任评分:68.8/100
- 代码片段:192+
- 可用于生产环境的 Python Kafka 客户端
Temporal
- Context7 ID:
/websites/temporal_io - 信任评分:80.9/100
- 代码片段:3,769+
- 用于持久执行的工作流编排
安装
Python:
pip install confluent-kafka celery[redis] temporalio aio-pika redis
TypeScript/Node.js:
npm install kafkajs bullmq @temporalio/client amqplib ioredis
Rust:
cargo add rdkafka lapin async-nats redis
Go:
go get github.com/confluentinc/confluent-kafka-go
go get github.com/hibiken/asynq
go get go.temporal.io/sdk
实用工具
使用脚本自动化设置:
- Kafka 设置:运行
python scripts/kafka_producer_consumer.py使用测试工具 - 架构验证:运行
python scripts/validate_message_schema.py验证事件架构
相关技能
- api-patterns:用于异步作业提交的 API 设计
- realtime-sync:用于作业状态更新的 WebSocket/SSE
- feedback:用于作业完成的 Toast 通知
- databases-*:用于事件日志的持久化存储
- observability:用于队列操作的跟踪与指标
评论
支持 Markdown