1 rabbitmq消息处理过程
生产者将信息发送到交换机,交换机根据绑定键将信息发送到队列,消费者从队列中获取数据。
交换机知道信息到达时应该如何处理它。
如何处理就是根据交换机的类型确定的。
2 交换机以及绑定
交换机类型: direct, topic, headers, fanout
关于交换机和队列,存在绑定关系,具体语法如下:
channel.queue_bind(exchange=exchange_name,
queue=queue_name)
表示队列对来自于某个交换机上的信息感兴趣
channel.queue_bind(exchange=exchange_name,
queue=queue_name,
routing_key='black')
绑定可以添加额外的参数: routing_extra,,为了避免与basic_publish
参数的混淆,我们称它为绑定键binding key。
这意味着绑定键依赖于交换机类型,对于fanout,忽略绑定键。
2.1 fanout交换机
如果交换机类型为: fanout:广播信息到所有队列上
消息队列模型如下:
Producer ---> Exchange(type=fanout) ---> amq.gen-RQ6... ---> Consumer1
---> amq.gen-RQ6... ---> Consumer2
2.2 direct交换机
交换机类型如果为: direct.那么绑定键会正确匹配消息的路由键。
消息队列模型如下:
---> RoutingKey(error) ---> amqp.gen-S9b... ---> Consumer1
Producer ---> Exchange(type=direct) ---> RoutingKey(info) ---> amqp.gen-Ag1... ---> Consumer2
---> RoutingKey(error) ---> amqp.gen-Ag1... ---> Consumer2
---> RoutingKey(warning) ---> amqp.gen-Ag1... ---> Consumer2
多个队列可以通过相同的绑定键绑定。
实际上就是交换机类型为direct,绑定键是同样的,但是绑定到多个队列上。
2.3 topic交换机
交换机类型如果为: topic, 它就没有routing_key。它必须是一个字符串列表,
以点号分隔。例如:
"quick.orange.rabbit"
绑定键也必须是以相同格式,。
* 可以代替任何一个字符
# 可以替代0或多个字符
消息队列模型如下:
-----> RoutingKey (*.orange.*)--->Queue1---> Consumer1
Producer---> Exchange(type=topic) -----> RoutingKey (*.*.rabbit)--->Queue2---> Consumer2
-----> RoutingKey (lazy.#) --->Queue2---> Consumer2
如果topic交换机的绑定键用 # ,它的行为就变成了fanout的交换机类似;
如果topic交换机的绑定键用 不用#和*, 它的行为就变成了和direct的交换机类似。
3 基于rabbitmq消息队列的rpc远程进程通信
客户端需要调用服务端的方法,
模型如下:
Client-----> Request,reply_to=CallBackQueue,correlation_id=abc --------------> rpc_queue ------------->Server
<----- Reply, correlation_id=abc <-----------reply_to=CallBackQueue<-----
处理过程:
1) 客户端启动,创建一个匿名的回调队列
2) 对于一个RPC请求,客户端发送的信息带有两个属性:
reply_to: 表示回调的队列, correlation_id: 对每个请求的唯一值
3) 请求被发送到rpc队列
4) RPC服务端监听队列上的请求,当请求出现,它完成任务,并发送一个携带有结果的消息到客户端,
将消息发送到回调队列
5) 客户端等待回调队列上的数据,当消息出现,它检测correlation_id是否正确。
4 rabbitmq常用命令
4.1 列出所有交换机
sudo rabbitmqctl list_exchanges
返回结果样例如下:
ceilometer topic
ceilometer.agent.compute_fanout fanout
q-metering-plugin_fanout fanout
解释:
上述第一列表示: 交换机名称, 上述第二列表示: 交换机类型
4.2 列出所有绑定
sudo rabbitmqctl list_bindings
返回结果样例如下:
exchange alarm_notifier queue alarm_notifier []
exchange alarm_notifier.node-1.domain.tld queue alarm_notifier.node-1.domain.tld []
exchange alarm_notifier_fanout_b129173ee8d9440286a42faf19355a94 queue alarm_notifier_fanout_b129173ee8d9440286a42faf19355a94 []
exchange ceilometer.agent.compute queue ceilometer.agent.compute []
exchange ceilometer.agent.compute.node-1.domain.tld queue ceilometer.agent.compute.node-1.domain.tld []
exchange ceilometer.agent.compute.node-2.domain.tld queue ceilometer.agent.compute.node-2.domain.tld []
exchange ceilometer.agent.compute.node-3.domain.tld queue ceilometer.agent.compute.node-3.domain.tld []
exchange ceilometer.agent.compute_fanout_5cd3fcae2e7e47f7a76c14833a9a97f2 queue ceilometer.agent.compute_fanout_5cd3fcae2e7e47f7a76c14833a9a97f2 []
exchange ceilometer.agent.compute_fanout_b5d6a8b206944688b0b62b3a6f7f7e4b queue ceilometer.agent.compute_fanout_b5d6a8b206944688b0b62b3a6f7f7e4b []
exchange metering.sample queue metering.sample []
exchange notifications.error queue notifications.error []
exchange notifications.info queue notifications.info []
exchange notifications.sample queue notifications.sample []
解释:
上述各个列含义如下
exchange exchange_name queue queue_name
分析:
nova exchange notifications.error queue notifications.error []
nova exchange notifications.info queue notifications.info []
nova exchange notifications.sample queue notifications.sample []
可以看到经过oslo.messaging封装后,
真实exchange名称=exchange名称 + oslo.messaging对象调用的方法名称(例如: info, error, sample)
队列名称=真实exchange名称
所以说: oslo.messaging对rabbitmq还是封装了很多东西
4.3 列出所有队列
rabbitmqctl list_queues
返回结果示例:
ceilometer.agent.compute 0
ceilometer.agent.compute.node-1.domain.tld 0
ceilometer.agent.compute.node-2.domain.tld 0
ceilometer.agent.compute.node-3.domain.tld 0
ceilometer.agent.compute_fanout_5cd3fcae2e7e47f7a76c14833a9a97f2 0
ceilometer.agent.compute_fanout_b5d6a8b206944688b0b62b3a6f7f7e4b 0
解释:
上述各个列含义如下
队列名称 消息个数
注意:消费者创建队列,不是生产者
参考:
[1] http://www.rabbitmq.com/tutorials/tutorial-one-python.html
[2] http://www.rabbitmq.com/tutorials/tutorial-two-python.html
[3] http://www.rabbitmq.com/tutorials/tutorial-three-python.html
[4] http://www.rabbitmq.com/tutorials/tutorial-four-python.html
[5] http://www.rabbitmq.com/tutorials/tutorial-five-python.html
[6] http://www.rabbitmq.com/tutorials/tutorial-six-python.html