Openstck RPC通信(以cinder为例)

Cinder组件简介

Openstack 的主要组件有 Nova、Cinder、Neutron、Glance 等,分别负责云平台的计算、存储、网络资源管理。OpenStack 各组件之间是通过 REST 接口进行相互通信,而各组件内部则采用了基于 AMQP 模型的 RPC 通信。下面以cinder组件为例,讲述RPC调用过程。

在讲述 OpenStack RPC 通信机制之前,首先介绍一下 cinder 系统架构,Cinder 主要由 3 个组件组成,cinder-api, cinder-scheduler 和 cinder-volume:

  • Cinder-api 是 cinder 服务的 endpoint,提供 rest 接口,负责处理 client 请求,并将 RPC 请求发送至 cinder-scheduler 组件。

  • Cinder-scheduler 负责 cinder 请求调度,其核心部分就是 scheduler_driver, 作为 scheduler manager 的 driver,负责 cinder-volume 具体的调度处理,发送 cinder RPC 请求到选择的 cinder-volume。

  • Cinder-volume 负责具体的 volume 请求处理,由不同后端存储提供 volume 存储空间。目前各大存储厂商已经积极地将存储产品的 driver 贡献到 cinder 社区。

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。

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
    OpenStack 目前支持的基于 AMQP 模型的 RPC backend 有 RabbitMQ、QPid、ZeroMQ,对应的具体实现模块在 cinder 项目下 Openstack/common/RPC/目录下,impl_*.py 分别为对应的不同 backend 的实现。

创建 volume 的 RPC 通信过程

Create volume 的过程可以看做是两个阶段的 RPC 请求处理,第一阶段:

  • Client 即 cinder-api 调用 RPC.cast 发送消息,RPC.cast 创建 Topic Publisher 对象,topic 为 cinder-scheduler,也就是消息的 Routing Key,Exchange name 为 OpenStack,消息体中标记了消息接收者即 Server 所需要调用的方法“create_volume”;
  • Exchange 接收到消息,根据 Routing Key 将消息发送至 Message Queue cinder-scheduler 上,这个 Message Queue 是由 cinder-scheduler 服务的 Topic Consumer 订阅的,因此,cinder-scheduler 服务将接收到 create_volume 的消息
  • Consumer 调用注册的 RPC_dispatcher,即 cinder-scheduler manager,然后由 cinder-scheduler manager 调用 RPC 处理方法 create_volume

Create volume 请求的第二阶段由 cinder-scheduler 的 create_volume 方法调用发起,即 cinder-scheduler 使用 filter and weighing 算法选取了 cinder-volume 的 host 用于创建 volume,则调用 RPC.cast 请求向 host 发送 RPC 请求,这个阶段 cinder-scheduler 为请求发起者即 client,cinder-volume 为请求处理者即 server。

  • Cinder-scheduler 调用 RPC.cast,Exchange name 为 Openstack, routing-key 为 cinder-volume:host
  • Exchange 接收到消息,根据 Routing Key 将消息发送到队列 cinder-volume:host 上
  • 在主机 host 上的 Cinder-volume consumer 从 Queue 中接收到 message,回调 RPC_dispatcher 即 cinder-volume manager
  • Cinder-volume manger 根据消息体中 method 信息,调用 create_volume 方法,创建 volume

OpenStack Notification

OpenStack Notification 机制用于通知用户或者开发者当前请求执行状态,在 RPC 通信角色一节中介绍了 Notification Publisher,其实就是一种 Topic Publisher。

启用 Notification 机制,需要在 Cinder 配置文件中配置 notification_driver。

notification_driver = cinder.Openstack.common.notifier.RPC_notifier

Notification priority 提供了 DEBUG, WARN, INFO, ERROR, CRITICAL 五个级别的消息,Cinder 的 notification 的 Exchange name 是 Openstack,topic 是 notifications.priority,例如 notifications.info

Cinder 项目默认的 Exchange name 是 OpenStack,由于 Exchange 负责信息转发,因此能够看到所有流入 Exchange 的消息,如果我们仅想要查看 notification 类型的消息,也可以自己创建 Message Queue,使用 Routing key 绑定到 Exchange 上

一种创建 Queue 的简单方法是使用 Qpid 提供的客户端工具 qpid-config。关于 qpid-config 工具的具体使用方法可以通过帮助文档来获取。

创建接受 notification INFO 级别的消息,则执行如下操作

  • 创建 Message Queue

    qpid-config add Queue notification_info

    可以通过 qpid-tool 中使用 list Queue 查看已经创建了以 notification.info 为名的 Queue,这里仅仅是创建了 Message Queue

  • 建立 Routing Key

    qpid-config [OPTIONS] bind   <Exchange-name> <Queue-name> [binding-key]
    qpid-config bind Openstack notification_info notifications.info

    建立了 Exchange 和 Message Queue 之间的路由关系,Routing Key 为 notifications.info,只要 Exchange 接收到 Routing Key 为 notifications.info 的消息将会将消息转发至名字为 notification_info 的 Queue 中

  • 查看 notifications.info 的消息

    ./drain -t 1000 notification_info

使用 cinder 命令创建一个 volume,则能够查看到 notifications.info 的消息内容了。