溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Nova怎么向消息總線發(fā)送通知

發(fā)布時(shí)間:2022-01-04 14:16:48 來(lái)源:億速云 閱讀:170 作者:iii 欄目:云計(jì)算

本篇內(nèi)容介紹了“Nova怎么向消息總線發(fā)送通知”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

與其他OpenStack服務(wù)類似,Nova通過oslo.messaging提供的Notifier類向消息總線發(fā)送通知。 從通知使用者的角度來(lái)看,通知由兩個(gè)部分組成 : 由oslo.messaging定義的固定結(jié)構(gòu)的envelope 和 由發(fā)出通知的服務(wù)定義的有效負(fù)載。 envelope的格式如下:

{
    "priority": <string, selected from a predefined list by the sender>,
    "event_type": <string, defined by the sender>,
    "timestamp": <string, the isotime of when the notification emitted>,
    "publisher_id": <string, defined by the sender>,
    "message_id": <uuid, generated by oslo>,
    "payload": <json serialized dict, defined by the sender>
}

在Nova中有兩種類型的通知 : 具有非版本負(fù)載的 legacy通知 和 具有版本負(fù)載的新通知。

未版本控制的通知

Nova代碼使用了nova.rpc.get的通知調(diào)用來(lái)得到已被配置的oslo.messaging通知對(duì)象然后它使用oslo提供在 Notifier 對(duì)象上的函數(shù)來(lái)發(fā)出通知。 返回的Notifier對(duì)象的配置取決于 get notifier call 的參數(shù) 和 oslo.messaging 配置選項(xiàng)driver和topics 的值。 Nova中有 notification 配置選項(xiàng),它指定特定的通知類型,如: notifications.notify_on_state_change, notifications.default_level等。

未版本控制的 notifications 的有效負(fù)載的結(jié)構(gòu)是在發(fā)出通知的代碼中定義的,并且不存在這種格式的文檔或強(qiáng)制向后兼容性契約。

版本控制的通知

創(chuàng)建版本通知概念是為了修正非版本通知的缺點(diǎn)。 發(fā)出通知的 envelope 結(jié)構(gòu)與oslo.messaging提供的未版本化通知案例中的 envelope 結(jié)構(gòu)相同。 但是,有效負(fù)載不是一個(gè)隨意的表單字典,而是一個(gè)序列化的 oslo versionedobject。

例如, service.update notification 的 wire 格式 看起來(lái)如下:

{
    "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作為一個(gè)有效負(fù)載提供了一個(gè)版本號(hào)給消費(fèi)者,這樣消費(fèi)者就可以檢測(cè)到負(fù)載的結(jié)構(gòu)是否發(fā)生了變化。 Nova提供了關(guān)于版本化通知的有效負(fù)載的以下契約:

  • 如果且僅當(dāng) payload 的nova object.data 字段 的語(yǔ)法或語(yǔ)義被改變時(shí),由 payload 的 nova object.version 字段定義的 負(fù)載版本會(huì)增加。

  • 一個(gè)小版本的bump表示一個(gè)向后兼容的變更,這意味著只有新的字段被添加到有效負(fù)載中,這樣一個(gè)寫得很好的消費(fèi)者仍然可以在沒有任何變化的情況下使用新的有效負(fù)載。

  • 一個(gè)主版本的bump指示了負(fù)載的向后不兼容的更改,這可能意味著在有效負(fù)載中刪除字段、類型更改等。

  • 除了 ‘nova_object.data’ 和‘nova_object.version’,在每個(gè)負(fù)載上還有一個(gè)額外的 nova_object.name字段。

有一個(gè)Nova配置參數(shù)是 notifications.notification_format ,用于指定哪種通知可被NOVA發(fā)出。 可能的值有 unversioned, versioned,或同時(shí)設(shè)置兩種值。默認(rèn)情況兩種都可以。

versioned notification會(huì)被發(fā)送到與 legacy notifications 不同的 topic 。默認(rèn)情況下他們被發(fā)送到 versioned_notifications,但是它是可以在 nova.conf 文件里被修改 versioned_notifications_topic 配置選項(xiàng)的。

如何添加版本化的通知

為了從Nova代碼支持上面的契約,每個(gè)版本的通知都與oslo versionedobjects建模。 每個(gè)版本的通知類都應(yīng)該繼承 nova.notifications.objects.base.NotificationBase,它已經(jīng)定義了通知的三個(gè)強(qiáng)制性字段, event_type, publisher_id 和priority 。新通知類應(yīng)該添加一個(gè)新的字段負(fù)載,它帶有個(gè)合適的payload類型。 通知的負(fù)載對(duì)象應(yīng)當(dāng)繼承 nova.objects.notifications.base.NotificationPayloadBase類同時(shí)應(yīng)將有效負(fù)載的字段定義為versionedobject字段。 下一部分描述基類。

nova.notifications.objects.base模塊

Nova怎么向消息總線發(fā)送通知

請(qǐng)注意,通知對(duì)象不應(yīng)注冊(cè)到NovaObjectRegistry,以避免將nova內(nèi)部對(duì)象與通知對(duì)象混合在一起。 在每個(gè)具體的通知對(duì)象上使用register通知裝飾器來(lái)替代它。

下面的代碼例子為新的 notification(myobject.update)定義了必要的模型類:

@notification.notification_sample('myobject-update.json')
@object_base.NovaObjectRegistry.register.register_notification
class MyObjectNotification(notification.NotificationBase):
    # Version 1.0: Initial version
    VERSION = '1.0'

    fields = {
        'payload': fields.ObjectField('MyObjectUpdatePayload')
    }


@object_base.NovaObjectRegistry.register.register_notification
class MyObjectUpdatePayload(notification.NotificationPayloadBase):
    # Version 1.0: Initial version
    VERSION = '1.0'
    fields = {
        'some_data': fields.StringField(),
        'another_data': fields.StringField(),
    }

之后,可以使用下面的代碼來(lái)填充和發(fā)送通知:

payload = MyObjectUpdatePayload(some_data="foo", another_data="bar")
MyObjectNotification(
    publisher=notification.NotificationPublisher.from_service_obj(
        <nova.objects.service.Service instance that emits the notification>),
    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":"<the name of the service>:<the host where the service runs>"
}

有可能通過為負(fù)載類添加一個(gè) SCHEMA字段來(lái)重用現(xiàn)有的versionedobject,它定義了現(xiàn)有對(duì)象字段和新有效載荷對(duì)象字段之間的映射。 例如 在定義通知的有效負(fù)載時(shí)service.status通知重用現(xiàn)有的 nova.objects.service.Service 對(duì)象:

@notification.notification_sample('service-update.json')
@object_base.NovaObjectRegistry.register.register_notification
class ServiceStatusNotification(notification.NotificationBase):
    # Version 1.0: Initial version
    VERSION = '1.0'

    fields = {
        'payload': fields.ObjectField('ServiceStatusPayload')
    }

@object_base.NovaObjectRegistry.register.register_notification
class 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 字段, 那么在開始發(fā)送通知前需要通過調(diào)用 populate_schema 來(lái)填充 payload object:

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

上面的代碼會(huì)在線生成一個(gè)JSON格式的數(shù)據(jù),格式類似于上面的event_type為myobject.update的格式。

SCHEMA 字段的數(shù)據(jù)格式遵循如下方法:

<payload field name which needs to be filled>:
(<name of the parameter of the populate_schema call>,<the name of a field of the parameter object>)

定義在 SCHEMA 字段中的映射具有以下語(yǔ)義。 當(dāng) populate_schema 函數(shù)被調(diào)用時(shí), SCHEMA字段的內(nèi)容被枚舉,   并且 指向參數(shù)對(duì)象的字段值被復(fù)制到請(qǐng)求的payload字段中。 因此,在上面的示例中, payload 對(duì)象的host字段由service對(duì)象的host字段的值填充,該值作為參數(shù)傳遞給populate_schema調(diào)用。

通知的有效負(fù)載對(duì)象可以重用來(lái)自多個(gè)現(xiàn)有對(duì)象的字段。 同樣,通知可以在其有效負(fù)載中同時(shí)擁有新的和重用的字段。

注意,通知的發(fā)布者實(shí)例有兩種不同的方式創(chuàng)建。 通過帶有 host 和binary 字符串參數(shù)實(shí)例 NotificationPublisher 對(duì)象的方法創(chuàng)建,或者通過 NotificationPublisher.from_service_obj 方法來(lái)生成 Service 對(duì)象。

Versioned notifications 有一個(gè)示例文件存儲(chǔ)在doc/sample_notifications 目錄并且 notification對(duì)象應(yīng)該用 notification_sample 裝飾器來(lái)裝飾。例如 service.update 通知有個(gè)示例文件存儲(chǔ)在 doc/sample_notifications/service-update.json 并且 ServiceUpdateNotification 類相應(yīng)地被裝飾。

  Notification payload 類 可以使用繼承 以避免在nova代碼中復(fù)制常見的有效負(fù)載片段。 然而,應(yīng)該在通知中創(chuàng)建直接用于通知的 leaf 類,以避免將來(lái)需要增加額外的繼承級(jí)別,從而改變了在載荷類中出現(xiàn)的 leaf 類的名稱。 如果不能避免這一點(diǎn),唯一的變化是重命名,那么新的有效負(fù)載的版本應(yīng)該與重命名之前的舊有效負(fù)載相同。

“Nova怎么向消息總線發(fā)送通知”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI