Services, Managers and Drivers

对于刚接触 nova 的人来说,Services、Managers 和 Drivers 的职责划分可能会有些令人困惑。本文档旨在概述职责划分,以便更容易理解系统。

目前,Managers 和 Drivers 是通过 flags 指定并使用 utils.load_object() 加载的。这种方法允许它们实现为单例、类、模块或对象。只要 flag 指定的路径指向一个对象(或一个返回对象的调用者),并且该对象响应 getattr,它就可以作为 manager 或 driver 工作。

The nova.service Module

运行在主机上的所有 worker 的通用节点基类。

class nova.service.Service(host, binary, topic, manager, report_interval=None, periodic_enable=None, periodic_fuzzy_delay=None, periodic_interval_max=None, *args, **kwargs)

Bases: Service

运行在主机上的二进制文件的服务对象。

服务接收一个 manager,通过监听基于 topic 的队列来实现 rpc。它还会定期在 manager 上运行任务,并将其状态报告给数据库 services 表。

basic_config_check()

在开始处理之前执行基本配置检查。

classmethod create(host=None, binary=None, topic=None, manager=None, report_interval=None, periodic_enable=None, periodic_fuzzy_delay=None, periodic_interval_max=None)

实例化类并返回应用程序对象。

参数:
  • host – 默认为 CONF.host

  • binary – 默认为可执行文件的基本名称

  • topic – 默认为 bin_name - ‘nova-’ 部分

  • manager – 默认为 CONF.<topic>_manager

  • report_interval – 默认为 CONF.report_interval

  • periodic_enable – 默认为 CONF.periodic_enable

  • periodic_fuzzy_delay – 默认为 CONF.periodic_fuzzy_delay

  • periodic_interval_max – 如果设置,则为两次运行之间的最大等待时间

kill()

在数据存储中销毁服务对象。

注意:虽然此方法仅在测试中使用,但将其放在此处很方便,这样测试就可以轻松干净地停止和移除 service_ref。

periodic_tasks(raise_on_error=False)

以固定间隔运行的任务。

reset()

重置服务。

start()

启动服务。

这包括启动 RPC 服务、初始化定期任务等。

stop()

停止服务并进行清理。

nova.service.process_launcher()
nova.service.serve(server, workers=None)
nova.service.setup_profiler(binary, host)
nova.service.wait()

The nova.manager Module

Base Manager class.

Managers 负责系统的某个方面。它是与系统一部分代码相关的逻辑分组。通常,其他组件应该使用 manager 来更改其负责的组件。例如,需要以某种方式处理卷的其他组件,应该通过调用 VolumeManager 的方法来处理,而不是直接更改数据库中的字段。这允许我们将所有与卷相关的代码保存在同一个地方。

例如,其他组件如果需要以某种方式处理卷,应该通过调用 VolumeManager 的方法来实现,而不是直接修改数据库中的字段。这使得我们可以将所有与卷相关的代码保存在同一个地方。

我们采纳了“智能 manager 和哑数据”的基本策略,这意味着不是将方法附加到数据对象上,而是让组件调用 manager 方法来操作数据。

应直接调用 managers 上可以本地执行的方法。如果某个方法必须在远程主机上执行,则应通过 rpc 调用包装 manager 的服务来完成。

Managers 应负责大部分的 db 访问和非实现特定的数据。任何不能泛化的实现特定内容都应由 Driver 完成。

总的来说,我们倾向于有一个 manager 配合多个 driver 来处理不同的实现,但有时拥有多个 manager 也是有意义的。您可以这样理解:在 manager 层面抽象不同的整体策略(FlatNetwork vs VlanNetwork),在 driver 层面抽象不同的实现(LinuxNetDriver vs CiscoNetDriver)。

Managers 通常会为主机的初始设置或周期性任务提供方法给包装服务。

此模块提供了 Manager,它是 managers 的基类。

class nova.manager.Manager(host=None, service_name='undefined')

Bases: PeriodicTasks

cleanup_host()

在服务关闭时执行清理工作的钩子。

子类应重写此方法。

init_host(service_ref)

在请求启动服务时执行其他 manager 初始化工作的钩子。这在创建任何服务记录之前调用,但如果该服务已存在记录,则会提供。

子类应重写此方法。

参数:

service_ref – 如果存在,则为 objects.Service,否则为 None。

periodic_tasks(context, raise_on_error=False)

以固定间隔运行的任务。

post_start_hook()

钩子,允许 manager 在服务创建 RPC 消费者并开始“运行”后立即执行其他启动工作。

子类应重写此方法。

pre_start_hook(service_ref)

钩子,允许 manager 在创建任何 RPC 队列/消费者之前执行其他启动工作。这在其他初始化成功并创建服务记录后调用。

子类应重写此方法。

参数:

service_ref – 此服务的 nova.objects.Service

reset()

在 SIGHUP 时调用的钩子,以信号通知 manager 重新读取任何动态配置或执行任何重新配置任务。

class nova.manager.ManagerMeta(names, bases, dict_)

Bases: NoopMeta, _PeriodicTasksMeta

用于跟踪特定类所有子类的元类。

此元类包装了使用它的类的每个公共方法(不以 _ 或 __ 开头)。使用 ManagerMeta 的类的所有子类也将被分析。

添加此元类需要将 __trace_args__ 属性添加到我们要修改的类中。该属性是一个字典,其中有一个必需的键:“name”。“name”定义了要跟踪的操作名称(例如,wsgi、rpc、db)。

但是,基于 OSprofiler 的跟踪只有在线程中先前已初始化 profiler 实例时才会发生,这只有在 nova.conf 中启用了配置文件并且 Nova API 的 API 调用包含了特定的标头时才可能发生。

class nova.manager.PeriodicTasks

Bases: PeriodicTasks

Implementation-Specific Drivers

Manager 通常会为其某些任务加载一个 driver。driver 负责特定的实现细节。任何在主机上运行 shell 命令或处理其他非 Python 代码的操作都应该发生在 driver 中。

Drivers 不应触碰数据库,因为数据库管理在 nova-conductor 中完成。

通常有意义的是为特定 driver 定义一个抽象基类(例如,VolumeDriver),以定义不同 driver 需要实现的各种方法。