Openstack之rabbitmq
rabbitmq 的工作流程和详细分析
1,rabbitmq 的 在openstack 项目中的调用过程分析
- 在openstack 的项目中需要 oslo.messaging 插件包
- oslo.messaging 的依赖包 kombu, pika.
在这里我们只分析 rabbitmq 相关的内容
OpenStack RPC 通信
Openstack 组件内部的 RPC(Remote Producer Call)机制的实现是基于 AMQP(Advanced Message Queuing Protocol)作为通讯模型,从而满足组件内部的松耦合性。AMQP 是用于异步消息通讯的消息中间件协议,AMQP 模型有四个重要的角色:
- Exchange:根据 Routing key 转发消息到对应的 Message Queue 中
- Routing key:用于 Exchange 判断哪些消息需要发送对应的 Message Queue
- Publisher:消息发送者,将消息发送的 Exchange 并指明 Routing Key,以便 Message Queue 可以正确的收到消息
- Consumer:消息接受者,从 Message Queue 获取消息
消息发布者 Publisher 将 Message 发送给 Exchange 并且说明 Routing Key。Exchange 负责根据 Message 的 Routing Key 进行路由,将 Message 正确地转发给相应的 Message Queue。监听在 Message Queue 上的 Consumer 将会从 Queue 中读取消息。
Routing Key 是 Exchange 转发信息的依据,因此每个消息都有一个 Routing Key 表明可以接受消息的目的地址,而每个 Message Queue 都可以通过将自己想要接收的 Routing Key 告诉 Exchange 进行 binding,这样 Exchange 就可以将消息正确地转发给相应的 Message Queue。图 2 就是 AMQP 消息模型。
图 2. AMQP 消息模型
AMQP 定义了三种类型的 Exchange,不同类型 Exchange 实现不同的 routing 算法:
- Direct Exchange:Point-to-Point 消息模式,消息点对点的通信模式,Direct Exchange 根据 Routing Key 进行精确匹配,只有对应的 Message Queue 会接受到消息
- Topic Exchange:Publish-Subscribe(Pub-sub)消息模式,Topic Exchange 根据 Routing Key 进行模式匹配,只要符合模式匹配的 Message Queue 都会收到消息 (模糊匹配)
- Fanout Exchange:广播消息模式,Fanout Exchange 将消息转发到所有绑定的 Message Queue
2, neutron 中所使用的 oslo.messaging 的服务分析
这个用dhcp-agent 服务为例子
1 | # neutron/cmd/eventlet/agents/dhcp.py |
分析rpc 服务的代码流程
1, rpc 服务的 server 端 也就是 receive 端接受消息
- rpc server 端就是一个 接受 消息端
- rpc server 端需要一个 回调方法 collback 方法
- rpc server 端是创建 consumer (消费者)
分析 oslo.messaging 包的分析 oslo_messaging/_drivers/./impl_rabbit.py
1 | # 创建一个 direct 队列 |
RPC 发送请求
Client 端发送 RPC 请求由 publisher 发送消息并声明消息地址,consumer 接收消息并进行消息处理,如果需要消息应答则返回处理请求的结果消息。OpenStack RPC 模块提供了 :
rpc.call,
rpc.cast,
rpc.fanout_cast,
三种 RPC 调用方法,发送和接收 RPC 请求。
rpc.call 发送 RPC 请求并返回请求处理结果,
请求处理流程如图 5 所示,
由 Topic Publisher 发送消息,
Topic Exchange 根据消息地址进行消息转发至对应的 Message Queue 中,
Topic Consumer 监听 Message Queue,发现需要处理的消息则进行消息处理,
并由 Direct Publisher 将请求处理结果消息,请求发送方创建 Direct Consumer 监听消息的返回结果
rpc.cast 发送 RPC 请求无返回,请求处理流程如图 6 所示,与 rpc.call 不同之处在于,不需要请求处理结果的返回,因此没有 Direct Publisher 和 Direct Consumer 处理。
图 7. RPC.fanout 消息处理
cast, call 代码分析
1 | # cast 没有返回结果 |