go语言rpc性能对比 go语言运行效率( 四 )


以下是 AMQP 中的几个必知的概念:
Publisher:消息发布者
Queue:用来保存消息的存储空间,消息没有被receiver前 , 保存在队列中 。
Exchange:用来接收Publisher发出的消息 , 根据Routing key 转发消息到对应的Message Queue中,至于转到哪个队列里,这个路由算法又由exchange type决定的 。
Exchange type:主要四种描述exchange的类型 。
direct:消息路由到满足此条件的队列中(queue,可以有多个):routing key = binding key
topic:消息路由到满足此条件的队列中(queue,可以有多个):routing key 匹配 binding pattern. binding pattern是类似正则表达式的字符串,可以满足复杂的路由条件 。
fanout:消息路由到多有绑定到该exchange的队列中 。
binding :binding是用来描述exchange和queue之间的关系的概念,一个exchang可以绑定多个队列,这些关系由binding建立 。前面说的binding key /binding pattern也是在binding中给出 。
为了让你明白这几者的关系 , 我画了一张模型图 。
关于AMQP,有几下几点值得注意:
前面铺垫了那么久,终于到了讲真实应用的场景 。在生产中RPC是如何应用的呢?
其他模型我不太清楚,在 OpenStack 中的应用模型是这样的
至于为什么要如此设计,前面我已经给出了自己的观点 。
接下来,就是源码解读 OpenStack ,看看其是如何通过rpc进行远程调用的 。如若你对此没有兴趣(我知道很多人对此都没有兴趣,所以不浪费大家时间),可以直接跳过这一节,进入下一节 。
目前Openstack中有两种RPC实现,一种是在oslo messaging,一种是在openstack.common.rpc 。
openstack.common.rpc是旧的实现,oslo messaging是对openstack.common.rpc的重构 。openstack.common.rpc在每个项目中都存在一份拷贝 , oslo messaging即将这些公共代码抽取出来,形成一个新的项目 。oslo messaging也对RPC API 进行了重新设计,对多种 transport 做了进一步封装,底层也是用到了kombu这个AMQP库 。(注:Kombu 是Python中的messaging库 。Kombu旨在通过为AMQ协议提供惯用的高级接口,使Python中的消息传递尽可能简单,并为常见的消息传递问题提供经过验证和测试的解决方案 。)
关于oslo_messaging库,主要提供了两种独立的API:
因为 notify 实现是太简单了 , 所以这里我就不多说了,如果有人想要看这方面内容,可以收藏我的博客(),我会更新补充 notify 的内容 。
OpenStack RPC 模块提供了 rpc.call,rpc.cast, rpc.fanout_cast 三种 RPC 调用方法,发送和接收 RPC 请求 。
rpc.call 和 .rpc.cast 从实现代码上看,他们的区别很小,就是call调用时候会带有wait_for_reply=True参数,而cast不带 。
要了解 rpc 的调用机制呢,首先要知道 oslo_messaging 的几个概念主要方法有四个:
transport:RPC功能的底层实现方法 , 这里是rabbitmq的消息队列的访问路径
transport 就是定义你如何访连接消息中间件,比如你使用的是 Rabbitmq , 那在 nova.conf中应该有一行transport_url的配置,可以很清楚地看出指定了 rabbitmq 为消息中间件,并配置了连接rabbitmq的user,passwd,主机 , 端口 。
target用来表述 RPC 服务器监听topic,server名称和server监听的exchange,是否广播fanout 。
rpc server 要获取消息 , 需要定义target,就像一个门牌号一样 。
rpc client 要发送消息,也需要有target,说明消息要发到哪去 。
endpoints:是可供别人远程调用的对象
RPC服务器暴露出endpoint,每个 endpoint 包涵一系列的可被远程客户端通过 transport 调用的方法 。直观理解,可以参考nova-conductor创建rpc server的代码,这边的endpoints就是 nova/manager.py:ConductorManager

推荐阅读