千家信息网

Nova怎么向消息总线发送通知

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,本篇内容介绍了"Nova怎么向消息总线发送通知"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!与其他O
千家信息网最后更新 2026年11月03日Nova怎么向消息总线发送通知

本篇内容介绍了"Nova怎么向消息总线发送通知"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

与其他OpenStack服务类似,Nova通过oslo.messaging提供的Notifier类向消息总线发送通知。 从通知使用者的角度来看,通知由两个部分组成 : 由oslo.messaging定义的固定结构的envelope 和 由发出通知的服务定义的有效负载。 envelope的格式如下:

{    "priority": ,    "event_type": ,    "timestamp": ,    "publisher_id": ,    "message_id": ,    "payload": }

在Nova中有两种类型的通知 : 具有非版本负载的 legacy通知 和 具有版本负载的新通知。

未版本控制的通知

Nova代码使用了nova.rpc.get的通知调用来得到已被配置的oslo.messaging通知对象然后它使用oslo提供在 Notifier 对象上的函数来发出通知。 返回的Notifier对象的配置取决于 get notifier call 的参数 和 oslo.messaging 配置选项driver和topics 的值。 Nova中有 notification 配置选项,它指定特定的通知类型,如: notifications.notify_on_state_change, notifications.default_level等。

未版本控制的 notifications 的有效负载的结构是在发出通知的代码中定义的,并且不存在这种格式的文档或强制向后兼容性契约。

版本控制的通知

创建版本通知概念是为了修正非版本通知的缺点。 发出通知的 envelope 结构与oslo.messaging提供的未版本化通知案例中的 envelope 结构相同。 但是,有效负载不是一个随意的表单字典,而是一个序列化的 oslo versionedobject。

例如, service.update notification 的 wire 格式 看起来如下:

{    "priority":"INFO",    "payload":{        "nova_object.namespace":"nova",        "nova_object.name":"ServiceStatusPayload",        "nova_object.version":"1.0",        "nova_object.data":{            "host":"host1",            "disabled":false,            "last_seen_up":null,            "binary":"nova-compute",            "topic":"compute",            "disabled_reason":null,            "report_count":1,            "forced_down":false,            "version":2        }    },    "event_type":"service.update",    "publisher_id":"nova-compute:host1"}

序列化的oslo versionedobject作为一个有效负载提供了一个版本号给消费者,这样消费者就可以检测到负载的结构是否发生了变化。 Nova提供了关于版本化通知的有效负载的以下契约:

  • 如果且仅当 payload 的nova object.data 字段 的语法或语义被改变时,由 payload 的 nova object.version 字段定义的 负载版本会增加。

  • 一个小版本的bump表示一个向后兼容的变更,这意味着只有新的字段被添加到有效负载中,这样一个写得很好的消费者仍然可以在没有任何变化的情况下使用新的有效负载。

  • 一个主版本的bump指示了负载的向后不兼容的更改,这可能意味着在有效负载中删除字段、类型更改等。

  • 除了 'nova_object.data' 和'nova_object.version',在每个负载上还有一个额外的 nova_object.name字段。

有一个Nova配置参数是 notifications.notification_format ,用于指定哪种通知可被NOVA发出。 可能的值有 unversioned, versioned,或同时设置两种值。默认情况两种都可以。

versioned notification会被发送到与 legacy notifications 不同的 topic 。默认情况下他们被发送到 versioned_notifications,但是它是可以在 nova.conf 文件里被修改 versioned_notifications_topic 配置选项的。

如何添加版本化的通知

为了从Nova代码支持上面的契约,每个版本的通知都与oslo versionedobjects建模。 每个版本的通知类都应该继承 nova.notifications.objects.base.NotificationBase,它已经定义了通知的三个强制性字段, event_type, publisher_id 和priority 。新通知类应该添加一个新的字段负载,它带有个合适的payload类型。 通知的负载对象应当继承 nova.objects.notifications.base.NotificationPayloadBase类同时应将有效负载的字段定义为versionedobject字段。 下一部分描述基类。

nova.notifications.objects.base模块

请注意,通知对象不应注册到NovaObjectRegistry,以避免将nova内部对象与通知对象混合在一起。 在每个具体的通知对象上使用register通知装饰器来替代它。

下面的代码例子为新的 notification(myobject.update)定义了必要的模型类:

@notification.notification_sample('myobject-update.json')@object_base.NovaObjectRegistry.register.register_notificationclass MyObjectNotification(notification.NotificationBase):    # Version 1.0: Initial version    VERSION = '1.0'    fields = {        'payload': fields.ObjectField('MyObjectUpdatePayload')    }@object_base.NovaObjectRegistry.register.register_notificationclass MyObjectUpdatePayload(notification.NotificationPayloadBase):    # Version 1.0: Initial version    VERSION = '1.0'    fields = {        'some_data': fields.StringField(),        'another_data': fields.StringField(),    }

之后,可以使用下面的代码来填充和发送通知:

payload = MyObjectUpdatePayload(some_data="foo", another_data="bar")MyObjectNotification(    publisher=notification.NotificationPublisher.from_service_obj(        ),    event_type=notification.EventType(        object='myobject',        action=fields.NotificationAction.UPDATE),    priority=fields.NotificationPriority.INFO,    payload=payload).emit(context)

上面的代码将生成以下通知 :

{    "priority":"INFO",    "payload":{        "nova_object.namespace":"nova",        "nova_object.name":"MyObjectUpdatePayload",        "nova_object.version":"1.0",        "nova_object.data":{            "some_data":"foo",            "another_data":"bar",        }    },    "event_type":"myobject.update",    "publisher_id":":"}

有可能通过为负载类添加一个 SCHEMA字段来重用现有的versionedobject,它定义了现有对象字段和新有效载荷对象字段之间的映射。 例如 在定义通知的有效负载时service.status通知重用现有的 nova.objects.service.Service 对象:

@notification.notification_sample('service-update.json')@object_base.NovaObjectRegistry.register.register_notificationclass ServiceStatusNotification(notification.NotificationBase):    # Version 1.0: Initial version    VERSION = '1.0'    fields = {        'payload': fields.ObjectField('ServiceStatusPayload')    }@object_base.NovaObjectRegistry.register.register_notificationclass ServiceStatusPayload(notification.NotificationPayloadBase):    SCHEMA = {        'host': ('service', 'host'),        'binary': ('service', 'binary'),        'topic': ('service', 'topic'),        'report_count': ('service', 'report_count'),        'disabled': ('service', 'disabled'),        'disabled_reason': ('service', 'disabled_reason'),        'availability_zone': ('service', 'availability_zone'),        'last_seen_up': ('service', 'last_seen_up'),        'forced_down': ('service', 'forced_down'),        'version': ('service', 'version')    }    # Version 1.0: Initial version    VERSION = '1.0'    fields = {        'host': fields.StringField(nullable=True),        'binary': fields.StringField(nullable=True),        'topic': fields.StringField(nullable=True),        'report_count': fields.IntegerField(),        'disabled': fields.BooleanField(),        'disabled_reason': fields.StringField(nullable=True),        'availability_zone': fields.StringField(nullable=True),        'last_seen_up': fields.DateTimeField(nullable=True),        'forced_down': fields.BooleanField(),        'version': fields.IntegerField(),    }    def populate_schema(self, service):        super(ServiceStatusPayload, self).populate_schema(service=service)

如果定义了 SCHEMA 字段, 那么在开始发送通知前需要通过调用 populate_schema 来填充 payload object:

payload = ServiceStatusPayload()payload.populate_schema(service=)ServiceStatusNotification(    publisher=notification.NotificationPublisher.from_service_obj(        ),    event_type=notification.EventType(        object='service',        action=fields.NotificationAction.UPDATE),    priority=fields.NotificationPriority.INFO,    payload=payload).emit(context)

上面的代码会在线生成一个JSON格式的数据,格式类似于上面的event_type为myobject.update的格式。

SCHEMA 字段的数据格式遵循如下方法:

:(,)

定义在 SCHEMA 字段中的映射具有以下语义。 当 populate_schema 函数被调用时, SCHEMA字段的内容被枚举, 并且 指向参数对象的字段值被复制到请求的payload字段中。 因此,在上面的示例中, payload 对象的host字段由service对象的host字段的值填充,该值作为参数传递给populate_schema调用。

通知的有效负载对象可以重用来自多个现有对象的字段。 同样,通知可以在其有效负载中同时拥有新的和重用的字段。

注意,通知的发布者实例有两种不同的方式创建。 通过带有 host 和binary 字符串参数实例 NotificationPublisher 对象的方法创建,或者通过 NotificationPublisher.from_service_obj 方法来生成 Service 对象。

Versioned notifications 有一个示例文件存储在doc/sample_notifications 目录并且 notification对象应该用 notification_sample 装饰器来装饰。例如 service.update 通知有个示例文件存储在 doc/sample_notifications/service-update.json 并且 ServiceUpdateNotification 类相应地被装饰。

Notification payload 类 可以使用继承 以避免在nova代码中复制常见的有效负载片段。 然而,应该在通知中创建直接用于通知的 leaf 类,以避免将来需要增加额外的继承级别,从而改变了在载荷类中出现的 leaf 类的名称。 如果不能避免这一点,唯一的变化是重命名,那么新的有效负载的版本应该与重命名之前的旧有效负载相同。

"Nova怎么向消息总线发送通知"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

字段 对象 版本 有效 代码 格式 面的 配置 参数 结构 情况 类型 总线 消息 内容 同时 契约 文件 方法 消费者 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 耶加雪菲 广东万易互联网科技有限公司惠州分公司 哈尔滨大商圈互联网科技有限公司 互联网科技行业发展 互联网和科技创新 互联网最新的科技有限公司 互联网金融 金融科技 上海致骋互联网科技 时间互联网络科技 成都仁贤领冠互联网科技有限公司 深圳互联网科技怎么样 汉立互联网科技有限公司联系电话 中盈科技互联网信息有限公司 四川慕妮娅互联网科技有限公司 科技互联网的核心竞争力 互联网科技实习生岗位 宁波跨境商互联网科技有限公司 中国新注册互联网科技 唐山双旺合互联网科技产业园 山东蛋芒互联网科技有限公司 科技与互联网发展 互联网未来科技 云电互联网科技 中国互联网金融科技基金 须眉科技是互联网公司吗 广州市恰铎互联网科技有限公司 本届互联网博览会上的黑科技 互联网科技融合创新 银川新华互联网科技学校是国营吗 高科技和互联网的现代国家
0