AMQP & Nova

OpenStack中的Nova各个服务之间以松耦合的方式使用AMQP进行通信(RPC)。使用AMQP的发布/订阅模式来进行RPC有如下优势:

         1) 客户端及服务端之间解耦:客户端不需要知道有哪些服务端以及服务端的地址;

         2) 客户端与服务端之间完全的同步性:客户端的RPC不需要服务端正好在运行;

         3) 远程调用的随机均衡:如果有多个服务端在运行,单向RPC会透明的分发到最一个可用的服务端。

 

         Nova用到了directfanouttopic三种类型的交换器(Exchange),整个架构图如下:

Nova基于AMQP实现了两种类型的RPC

rpc.call:请求响应类型,一个请求发送出去以后,需要等待响应;调用需要指定目标服务结点;

rpc.cast:单向RPC,只将请求发送出去,不需要等待结果;不关心请求由哪个服务结点完成。

 

Nova RPC结构

       下图说明了Nova RPC机制的主要结成部分(以使用RabbitMQ为例)。从调用关系上来说,Nova服务要么以调用方(InvokerAPIScheduler)角色来使用消息队列,要么以服务方(WorkerComputeVolumeNetwork)角色来使用消息队列。调用方通过rpc.callrpc.cast发送消息;服务方从消息队列接收消息,并对rpc.call请求做出响应。

         从生命周期上来说,TopicPublisherDirectConsumerDirectPublisher三部分是在rpc.call发起的时候创建的;而TopicConsumerNova的各个服务在启动时创建,并在服务结束时销毁。Nova中每一个服务在启动时会创建两个TopicConsumer:一个以NODE-TYPE为交换器键(Exchange Key),一个以NODE-TYPE.HOST为交换器键。

 

rpc.call调用流程

         1). 初始化一个TopicPublisher,发送消息到消息队列;在发送消息之前,初始化一个DirectConsumer(以消息ID为交换器的名称),用于等待响应消息;

         2). 消息被交换器分发到NODE-TYPE.HOST消息队列(下图中的topic.host),并被相应服务结点(根据host确定)的TopicConsumer获取到;

         3). 服务结点根据消息内容(调用函数及参数)调用相应服务;调用完成后,初始化一个DirectPublisher,并根据消息ID将响应消息发送到相应的消息队列;

         4). 响应消息被调用方的DirectConsumer获取到,调用完成。

 

rpc.cast调用流程

         1). 初始化一个TopicPublisher,并将消息发送到消息队列;

         2). 消息被交换器分发到NODE-TYPE消息队列(下图中的topic),并被相应服务的结点TopicConsumer获取到,然后根据消息内容调用相应服务完成调用。

 

==================================

上面是OpenStack文档里的主要内容,详细内容见这里。消息队列还有两种用法未在上面文档里说明。

 

实际上,Nova每个服务在启动时,还有创建第三个消费者:FanoutConsumer,不过这个Consumer只有一个应用:scheduler更新服务功能,通过rpc.fanout_cast调用(参见$NOVA_ROOT/nova/scheduler/api. update_service_capabilities)。

 

         另一种用法是rpc.notify,基于消息队列做成的一个事件通知机制,当有事件发生时,比如有计算结点挂起和继续时,会通过notifier.notify发送类似compute.instance.suspend或者compute.instance.resume的事件。详见$NOVA_ROOT/nova/notifier/api.notify $NOVA_ROOT/nova/notifier/rabbit_notifier.notify

猜你喜欢

转载自jzhihui.iteye.com/blog/1497031