您好,登錄后才能下訂單哦!
本篇內(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字段。 下一部分描述基類。
請(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í)用文章!
免責(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)容。