RPC服务实现分析
openstack的项目(如nova,cinder,glance以及neutron等)中,各个组件之间主要是通过REST API接口进行通信,而同一个组件内部(比如nova中的nova-scheduler与nova-compute通信)都采用基于AMQP通信模型的RPC通信。AMQP是一种提供统一消息服务的应用层标准协议,是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件同产品,不同的开发语言等条件的限制。在基于AMQP实现的模型中主要有5个比较重要的概念(角色):
- Exchange:相当于路由器,可以根据一定的规则(即Routing Key)最终把消息转发到相应的消息队列中去。
- Routing Key:用来告诉Exchange如何进行消息路由,即哪些消息应该发送到哪些消息队列中去。实际上它是一个虚拟地址,通过它可以确定如何路由一个特定消息。
- Binding Key:用来创建消息队列Queue和交换器Exchange绑定关系的实现。
- Publisher:消息的生产者,有人也称它为消息的发送者。它是消息的来源,消息发送时会指定目标Exchange以及Routing Key,这样可以保证正确的消息队列收到此消息。
- Consumer:消息的消费者,它主要是从消息队列中获取消息并处理。
不同角色之间的关系如下图所示,一个Exchange可以对接多个消息队列,根据不同的Routing Key,最终可以把消息分别发送到相应的消息队列中,不同的消费者最终从各自的消息队列中获取消息进行消费。
在openstack中,AMQP的实现主要使用的是RabbitMQ,RabbitMQ是一个开源的消息队列实现方式,是一种消息中间件,其官方的地址为https://www.rabbitmq.com,这里通过官方文档中的“Hello Word”案例演示一下RabbitMQ的消息收发过程,参考文档为https://www.rabbitmq.com/tutorials/tutorial-one-python.html,本示例设计的架构如下图所示,其中p为生产者Publisher,c为消费者consumer,hello为name为hello的消息队列queue:
首先建立生产者和RabbitMQ Server的连接。代码如下:
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
执行完上述代码之后,就建立一个和本地(localhost,如果要和远程机器则更换为相应的ip地址)的RabbitMQ Server的连接connection以及信道channel,信道channel是为了能够复用TCP连接connection而引入的概念,这样在需要建立多个连接的时候,通过复用TCP连接,能够很好地节约资源消耗。
接下来要创建接受端的消息队列,代码如下:
channel.queue_declare(queue='hello world')
到这里,我们便完成了消息发送的准备工作,下面就是把生产者的消息发送到这个消息队列中。生产者不能直接把消息发送到消息队列中,生产者发送的消息,首先应该到达exchange,然后再由Exchang