RabbitMQ Broker : mq代理,在服务器上。他包含了交换机(exchange)-》通过路由关键字(routing_key)找到对应的队列(queue)。再给消费者。
/* 声明 durable 队列;若服务器上已存在同名但参数不同的队列会失败 */
amqp_queue_declare(conn, CHANNEL_ID,
amqp_cstring_bytes(queue),
/*passive=*/0, /*durable=*/1,
/*exclusive=*/0, /*auto_delete=*/0,
amqp_empty_table);
队列声明时durable=1表示将消息保存在服务器队列上,即便服务器代理Broker挂了,下次连接上也能发给消费者。
/* 启动消费者;no_ack=1 即自动 ack,broker 投递后立即从队列移除 */
amqp_basic_consume(conn, CHANNEL_ID,
amqp_cstring_bytes(queue),
amqp_empty_bytes,
/*no_local=*/0, /*no_ack=*/1, /*exclusive=*/0,
amqp_empty_table);
一个queue可以绑定多个消费者,
┌──────────┐ ┌──────────┐
│ Producer │ │ Consumer │
│ (生产者) │ │ (消费者) │
└────┬─────┘ └────▲─────┘
│ │
│ ① publish(exchange, routing_key, body) │ ⑥ 推消息给消费者
▼ │
┌──────────────────────────────────────────────────────────────┐
│ RabbitMQ Broker │
│ │
│ ┌────────────┐ ②查路由表 ┌──────────┐ │
│ │ exchange │ ─────────────▶ │ queue │ │
│ │ (交换机) │ ③匹配命中复制 │ (队列) │ ──▶ ⑤存储等投 │
│ └────────────┘ └──────────┘ │
└──────────────────────────────────────────────────────────────┘
Producer 进程 Consumer 进程
┌───────────┐ ┌───────────┐
│ app 代码 │ │ app 代码 │
│ amqp_ │ │ amqp_ │
│ publish │ │ consume │
└─────┬─────┘ └─────▲─────┘
│ │
┌─────▼─────┐ ┌─────┴─────┐
│ rabbitmq-c│ │ rabbitmq-c│
│ 库 (TCP │ │ 库 (TCP │
│ 客户端) │ │ 客户端) │
└─────┬─────┘ └─────▲─────┘
│ │
│ TCP 连接 #1 TCP 连接 #2 │
│ (源端口随机, 目的 5172) (源端口随机, 目的 5172)
│ │
│ ┌────────────────────────┐ │
└──────────▶│ RabbitMQ Broker │─────────┘
│ (TCP 服务端, :5172) │
│ ┌──────────────────┐ │
│ │ exchange/queue │ │
│ │ 路由 + 缓冲 │ │
│ └──────────────────┘ │
└────────────────────────┘
▲
│
还可能有其他 Producer / Consumer
(每个都是独立 TCP 连接)
┌───────────────┬──────────────────────────────────────────┐
│ exchange 类型 │ 路由规则 │
├───────────────┼──────────────────────────────────────────┤
│ direct │ routing_key 完全等于 binding_key 才命中 │
├───────────────┼──────────────────────────────────────────┤
│ topic │ routing_key 按 */# 模式匹配 binding_key │
├───────────────┼──────────────────────────────────────────┤
│ fanout │ 忽略 routing_key,绑了的 queue 全收 │
├───────────────┼──────────────────────────────────────────┤
│ headers │ 按 message header 匹配,不用 routing_key │
└───────────────┴──────────────────────────────────────────┘