针对 cell 的消息队列连接切换

https://blueprints.launchpad.net/nova/+spec/cells-mq-connection-switching

为了使 Nova API 将 RPC 消息发送到 cell,必须使用目标 cell 的消息队列连接信息。Nova API 必须将 cell 消息队列信息传递给 RPC API 层。

问题描述

在 Cells v2 中,不再使用 nova-cells 代理,nova-api 将直接与实例的 cell 数据库和消息队列交互。实例 -> cell 映射存储在 API 级别数据库中的一个表中。每个 InstanceMapping 引用一个 CellMapping,CellMapping 包含 cell 的连接信息。我们需要一种方法将 CellMapping 中的消息队列连接信息传递给 RPC API 层,以便在收到针对实例的请求时,消息将被转发到实例所在的 cell。

用例

  • 运营商希望将他们的部署划分为 cell,以实现扩展、故障域和构建原因。在划分后,我们需要一种方法将消息路由到实例的 cell。

提议的变更

我们建议将 cell 的消息队列连接信息存储在 RequestContext 中,RPC API 层可以使用它与 cell 消息队列交互。目前,RPC API 层只能使用一个消息队列,它是全局传输。如果 RequestContext 中存在消息队列连接数据,我们希望能够动态创建传输。将添加一个字段 ‘mq_connection’ 到 RequestContext 中,以存储 cell 消息队列的传输对象。

当收到请求时,nova-api 将在 API 数据库中查找实例映射。它将从实例的 CellMapping 获取消息队列信息,并将传输对象存储在 RequestContext 的 ‘mq_connection’ 字段中。然后,RPC API 层将使用传输对象通过 ‘mq_connection’ 与 cell 消息队列交互,以转发消息。

备选方案

另一种方法是向 RPC API 方法添加一个参数,以便可以选择性地使用消息队列连接信息,而不是配置设置,并在发出目的地为另一个消息队列的调用时传递它。这将需要更改所有 RPC API 方法的签名以接受关键字参数,或者找到一种方法让相关的 RPC API 方法从这样的接口派生。此外,允许使用 RequestContext 中的一个字段来向 DB API 方法传递“db_connection”,向 DB API 模型查询传递“read_deleted”也有先例。

数据模型影响

REST API 影响

安全影响

RequestContext 中的消息队列连接字段可能包含敏感数据。

通知影响

其他最终用户影响

性能影响

此更改将基于 RequestContext 中的连接信息动态创建 RPC 传输对象。与通常用于单个消息队列的全局传输对象相比,这会产生一些开销。开销与 Cells v1 相同,因为 Transport 对象和 RPCClient 对象都是为发送到 cell 的每个消息动态创建的。如果开销成为问题,可以考虑使用基于 ‘mq_connection’ 的哈希值进行对象缓存,并采用过期方案。

  • 创建 Transport 对象涉及创建后端驱动程序对象和连接池,因此动态为每个消息创建它们无法利用连接池,每次都会建立一个新的连接到 broker。

其他部署者影响

开发人员影响

此更改意味着开发人员应注意 cell 消息队列连接信息包含在 RequestContext 中,并注意它可能包含敏感数据。开发人员需要使用从 CellMapping 获取消息队列连接信息并将其设置在 RequestContext 中的接口,以便与 cell 消息队列交互。

实现

负责人

主要负责人

melwitt

其他贡献者

工作项

  • 在 RequestContext 中添加消息队列连接字段

  • 在 nova.context 的上下文管理器中添加消息队列连接,根据 CellMapping 填充包含 cell 连接信息的 RequestContext

  • 修改 RPC 层和计算 RPC API 函数,以使用上下文中设置的消息队列连接信息(如果已设置)

依赖项

测试

Cells v2 测试改进将包括具有多个 cell 和使用多个 cell 进行升级的场景。然而,这超出了本规范描述的工作范围,使用当前 Tempest 和功能测试套件的结合来测试消息队列切换的功能测试就足够了。

文档影响

可以编写开发人员文档来描述如何使用新的接口。

参考资料

历史

修订版

发布名称

描述

Newton

引入