RabbitMQ 6种核心工作模式详解

415 阅读4分钟

RabbitMQ 提供了多种消息传递模式,以下是 6 种核心工作模式(基于常见分类和实际应用):

1. 简单模式(Simple Queue)

  • 结构:生产者 → 队列 → 消费者

image.png

  • 特点
    • 一个生产者发送消息到队列,一个消费者从队列中消费消息。
    • 使用默认的 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)

  • 结构:生产者 → 队列 → 多个消费者

image.png

  • 特点

    • 多个消费者共享一个队列,消息被均匀分配(轮询)。
    • 支持负载均衡,避免单个消费者过载。
  • 可能隐患

    • 存在资源竞争,高并发情况下,默认会产生某一个消息被多个消费者共同使用,可以设置一个开关(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类型) → 多个队列 → 多个消费者

image.png

  • 特点
    • 消息广播到所有绑定队列,忽略 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类型) → 队列 → 消费者

    image.png

  • 特点

    • 根据 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类型) → 队列 → 消费者

    image.png

  • 特点

    • 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_tocorrelation_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请求-响应分布式系统方法调用

注意事项

  1. 交换机类型:不同模式依赖不同类型的交换机(Fanout/Direct/Topic)。
  2. 幂等性:在实际应用中,需结合消息确认(ACK)、持久化等机制保障可靠性。
  3. 性能优化:发布/订阅模式可能消耗较多资源,需根据场景合理设计队列和消费者。

通过选择合适的工作模式,可以高效地实现消息传递、任务分发和分布式协作。