RabbitMQ 提供了多种消息传递模式,以下是 6 种核心工作模式(基于常见分类和实际应用):
1. 简单模式(Simple Queue)
- 结构:生产者 → 队列 → 消费者
- 特点:
- 一个生产者发送消息到队列,一个消费者从队列中消费消息。
- 使用默认的
direct交换机(无需显式声明)。
- 可能隐患:
- 消息可能没有被消费者正确处理,已经从队列中消失了,造成消息的丢失,这里可以设置成手动的ack,但如果设置成手动ack,处理完后要及时发送ack消息给队列,否则会造成内存溢出
- 适用场景:
- 简单的一对一消息传递,如订单提交后通知库存服务。
- 示例:
# 生产者 channel.basic_publish( exchange='', routing_key='simple_queue', body='Hello World' ) # 消费者 def callback(ch, method, properties, body): print("Received:", body.decode()) channel.basic_consume(callback, queue='simple_queue', no_ack=True)
2. 工作队列模式(Work Queue)
- 结构:生产者 → 队列 → 多个消费者
-
特点:
- 多个消费者共享一个队列,消息被均匀分配(轮询)。
- 支持负载均衡,避免单个消费者过载。
-
可能隐患:
- 存在资源竞争,高并发情况下,默认会产生某一个消息被多个消费者共同使用,可以设置一个开关(syncronize) 保证一条消息只能被一个消费者使用。
-
适用场景:
- 任务分发,如订单处理、批量数据计算。
-
示例:
# 消费者1 def callback1(ch, method, properties, body): print("Worker1 received:", body.decode()) # 消费者2 def callback2(ch, method, properties, body): print("Worker2 received:", body.decode()) channel.basic_consume(callback1, queue='work_queue') channel.basic_consume(callback2, queue='work_queue')
3. 发布/订阅模式(Publish/Subscribe)
- 结构:生产者 → 交换机(Fanout类型) → 多个队列 → 多个消费者
- 特点:
- 消息广播到所有绑定队列,忽略
routing_key。 - 实现“一对多”的消息分发(共享资源)。
- 消息广播到所有绑定队列,忽略
- 适用场景:
- 实时通知、日志广播、系统状态同步。
- 示例:
# 生产者 channel.exchange_declare(exchange='fanout_exchange', exchange_type='fanout') channel.basic_publish( exchange='fanout_exchange', routing_key='', # 忽略路由键 body='Broadcast Message' ) # 消费者1 result = channel.queue_declare(queue='', exclusive=True) channel.queue_bind(exchange='fanout_exchange', queue=result.method.queue) channel.basic_consume(callback, queue=result.method.queue) # 消费者2 result = channel.queue_declare(queue='', exclusive=True) channel.queue_bind(exchange='fanout_exchange', queue=result.method.queue) channel.basic_consume(callback, queue=result.method.queue)
4. 路由模式(Routing)
-
结构:生产者 → 交换机(Direct类型) → 队列 → 消费者
-
特点:
- 根据
routing_key精确匹配队列的绑定键(Binding Key)。 - 实现“定向分发”。
- 根据
-
适用场景:
- 按优先级处理消息(如 error/warning/info 日志)。
-
示例:
# 生产者 channel.exchange_declare(exchange='direct_exchange', exchange_type='direct') channel.basic_publish( exchange='direct_exchange', routing_key='error', # 路由键 body='Error Message' ) # 消费者1(绑定 error) channel.queue_bind(exchange='direct_exchange', queue='error_queue', routing_key='error') # 消费者2(绑定 warning) channel.queue_bind(exchange='direct_exchange', queue='warning_queue', routing_key='warning')
5. 主题模式(Topic)
-
结构:生产者 → 交换机(Topic类型) → 队列 → 消费者
-
特点:
routing_key支持通配符匹配(*匹配一个单词,#匹配多个单词)。- 实现灵活的模糊路由。
-
适用场景:
- 多层级消息过滤(如
stock.us.nyse.*表示纽约证券交易所的所有股票)。
- 多层级消息过滤(如
-
示例:
# 生产者 channel.exchange_declare(exchange='topic_exchange', exchange_type='topic') channel.basic_publish( exchange='topic_exchange', routing_key='stock.us.nyse.ibm', # 路由键 body='IBM Stock Data' ) # 消费者1(绑定 `stock.*.nyse.*`) channel.queue_bind(exchange='topic_exchange', queue='nyse_queue', routing_key='stock.*.nyse.*') # 消费者2(绑定 `stock.#`) channel.queue_bind(exchange='topic_exchange', queue='all_stock_queue', routing_key='stock.#')
6. 远程调用模式(RPC)
-
结构:客户端 → 请求队列 → 服务端 → 回复队列 → 客户端
-
特点:
- 客户端发送请求并等待响应(同步调用)。
- 使用
reply_to和correlation_id标识请求与响应的对应关系。
-
适用场景:
- 分布式系统中的远程方法调用(如查询接口)。
-
示例:
# 客户端 def on_response(ch, method, props, body): if props.correlation_id == corr_id: print("Response:", body.decode()) result = channel.queue_declare(queue='', exclusive=True) corr_id = str(uuid.uuid4()) channel.basic_publish( exchange='', routing_key='rpc_queue', body='Request Data', properties=pika.BasicProperties( reply_to=result.method.queue, correlation_id=corr_id ) ) # 服务端 def handle_rpc(ch, method, props, body): response = "Processed: " + body.decode() ch.basic_publish( exchange='', routing_key=props.reply_to, body=response, properties=pika.BasicProperties(correlation_id=props.correlation_id) ) channel.basic_consume(handle_rpc, queue='rpc_queue')
总结对比
| 模式 | 交换机类型 | 路由规则 | 典型场景 |
|---|---|---|---|
| 简单模式 | 默认(Direct) | 无 | 一对一消息传递 |
| 工作队列模式 | 默认(Direct) | 无 | 负载均衡任务分发 |
| 发布/订阅模式 | Fanout | 广播 | 实时通知、日志广播 |
| 路由模式 | Direct | 精确匹配 | 按优先级/类型分发消息 |
| 主题模式 | Topic | 通配符匹配 | 多层级消息过滤 |
| 远程调用模式(RPC) | Default | 请求-响应 | 分布式系统方法调用 |
注意事项
- 交换机类型:不同模式依赖不同类型的交换机(Fanout/Direct/Topic)。
- 幂等性:在实际应用中,需结合消息确认(ACK)、持久化等机制保障可靠性。
- 性能优化:发布/订阅模式可能消耗较多资源,需根据场景合理设计队列和消费者。
通过选择合适的工作模式,可以高效地实现消息传递、任务分发和分布式协作。