前篇文章對Dapr的狀态管理進行了解,本篇繼續對 訂閱/釋出 建構塊進行了解。
釋出訂閱的概念來自于事件驅動架構(EDA)的設計思想,這是一種讓程式(應用、服務)之間解耦的主要方式,通過釋出訂閱的思想也可以實作服務之間的異步調用。而大部分分布式應用都會依賴這樣的釋出訂閱解耦模式。

步驟:
釋出伺服器将消息發送到消息代理。
訂閱伺服器将綁定到消息代理上的訂閱。
消息代理将消息的副本轉發給感興趣的訂閱。
訂閱伺服器從其訂閱使用消息。
但是不同的消息中間件之間存在細微的差異,項目使用不同的産品需要實作不同的實作類,雖然是明智的決策,但必須編寫和維護抽象及其基礎實作。此方法需要複雜、重複且容易出錯的自定義代碼。
Dapr為了解決這種問題,提供開箱即用的消息傳送抽象和實作,封裝在 Dapr 建構基塊中。業務系統隻需調用跟據Dapr的要求實作訂閱釋出即可。
Dapr 釋出&訂閱建構基塊提供了平台無關的 API 架構來發送和接收消息。你的服務将消息釋出到一個命名主題(topic)。服務訂閱主題(topic)來使用消息。
服務在 Dapr Sidecar上調用 pub/sub API。 然後,Sidecar将調用一個預定義的 Dapr pub/sub 元件來封裝特定的消息代理産品。 下圖 顯示了 Dapr 釋出/訂閱 消息傳遞堆棧。
Dapr 釋出&訂閱建構基塊提供了一個與平台無關的 API 架構來發送和接收消息。
服務将消息釋出到指定主題, 業務服務訂閱主題以使用消息。
服務在 Dapr sidecar 上調用 pub/sub API。然後,sidecar 調用預定義 Dapr pub/sub 元件。
任何程式設計平台都可以使用 Dapr 本機 API 通過 HTTP 或 gRPC 調用建構基塊。若要釋出消息,請進行以下 API 調用:
上述調用中有幾個特定于 Dapr 的 URL 段:
<code><dapr-port></code> 提供 Dapr sidecar 偵聽的端口号。
<code><pub-sub-name></code> 提供所選 Dapr pub/sub 元件的名稱。
<code><topic></code> 提供消息釋出到的主題的名稱。
要啟用消息路由并為每個消息提供附加上下文,Dapr 使用 CloudEvents 1.0 規範 作為其消息格式。 使用 Dapr 應用程式發送的任何資訊都将自動包入 Cloud Events 信封中,<code>datacontenttype</code> 屬性使用 <code>Content-Type</code> 頭部值。
Dapr 實作以下 Cloud Events 字段:
<code>id </code>
<code>source</code>
<code>specversion</code>
<code>type</code>
<code>datacontenttype</code> (可選)
下面的示例顯示了 CloudEvent v1.0 中序列化為 JSON 的 XML 内容:
Dapr 應用程式可以訂閱已釋出的 topics。 Dapr 允許您的應用程式有兩種方法來訂閱 topics:
聲明式:其中定義在外部檔案中:
上面的示例顯示了 <code>test_topic</code>主題的事件訂閱,使用元件 <code>pubsub</code>。
<code>route</code> 告訴 Dapr 将所有主題消息發送到應用程式中的 <code>/TestPubSub</code> 端點。
<code>scopes</code> 為 frontend 應用啟用訂閱
程式設計方式:訂閱在使用者代碼中定義
Dapr 保證消息傳遞 at-least-once 語義。 這意味着,當應用程式使用釋出/訂閱 API 将消息釋出到主題時,Dapr 可確定此消息至少傳遞給每個訂閱者一次(at least once)
多個消費組、多個應用程式執行個體使用一個消費組,這些都将由 Dapr 自動處理。 當同一個應用程式的多個執行個體(相同的 ID) 訂閱主題時,Dapr 隻将每個消息傳遞給該應用程式的一個執行個體。
同樣,如果兩個不同的應用程式 (不同的 ID) 訂閱同一主題,那麼 Dapr 将每個消息僅傳遞到每個應用程式的一個執行個體。
預設情況下,支援Dapr釋出/訂閱元件的所有主題 (例如,Kafka、Redis、RabbitMQ) 都可用于配置該元件的每個應用程式。 為了限制哪個應用程式可以釋出或訂閱 topic,Dapr 提供了 topic 作用域限定。 這使您能夠讓應用程式允許釋出哪些主題以及應用程式允許訂閱哪些主題。
pub/sub 主題作用域限定
為每個 pub/sub 元件定義釋出/訂閱範圍。 您可能有一個名為 <code>pubsub</code> 的 pub/sub 元件,它有一組範圍設定,另一個 <code>pubsub2</code> 另有一組範圍設定。
要使用這個主題範圍,可以設定一個 pub/sub 元件的三個中繼資料屬性:
<code>spec.metadata.publishingScopes</code>
分号分隔應用程式清單& 逗号分隔的主題清單允許該 app 釋出資訊到主題清單
如果在 <code>publishingScopes</code> (預設行為) 中未指定任何内容,那麼所有應用程式可以釋出到所有主題
要拒絕應用程式釋出資訊到任何主題,請将主題清單留白 (<code>app1=;app2=topic2</code>)
例如, <code>app1=topic1;app2=topic2,topic3;app3=</code> 允許 app1 釋出資訊至 topic1 ,app2 允許釋出資訊到 topic2 和 topic3 ,app3 不允許釋出資訊到任何主題。
<code>spec.metadata.subscriptionScopes</code>
分号分隔應用程式清單& 逗号分隔的主題清單允許該 app 訂閱主題清單
如果在 <code>subscriptionScopes</code> (預設行為) 中未指定任何内容,那麼所有應用程式都可以訂閱所有主題
例如, <code>app1=topic1;app2=topic2,topic3</code> 允許 app1 訂閱 topic1 ,app2 可以訂閱 topic2 和 topic3
<code>spec.metadata.allowedTopics</code>
一個逗号分隔的允許主題清單,對所有應用程式。
如果未設定 <code>allowedTopics</code> (預設行為) ,那麼所有主題都有效。 <code>subscriptionScopes</code> 和 <code>publishingScopes</code> 如果存在則仍然生效。
<code>publishingScopes</code> 或 <code>subscriptionScopes</code> 可用于與 <code>allowedTopics</code> 的 conjuction ,以添加限制粒度
Dapr 可以在每個消息的基礎上設定逾時。 表示如果消息未從 Pub/Sub 元件讀取,則消息将被丢棄。 這是為了防止未讀消息的積累。 在隊列中超過配置的 TTL 的消息就可以說它挂了。
1、設定Pub/Sub元件:
本機預設下安裝了Redis Staram,在 Windows 上打開<code>%UserProfile%\.dapr\components\pubsub.yaml</code> 元件檔案以驗證:
2、實作釋出/訂閱功能 :
添加控制器(PubSubController)
Startup.cs中調整:
3、dapr運作程式:
4、調用釋出指令:
5、通過Dapr cli 釋出消息:
pub/sub 模式可幫助你分離分布式應用程式中的服務。 Dapr 釋出&訂閱建構基塊簡化了在應用程式中實作此行為。
通過 Dapr pub/sub,可以将消息釋出到特定 主題。建構基塊還将查詢服務,以确定 (訂閱) 主題。
可以通過 HTTP 或特定于語言的 SDK 之一(例如用于 Dapr 的 .NET SDK)本機使用 Dapr pub/sub。 .NET SDK 與 ASP.NET 平台緊密內建。
使用 Dapr,可以将受支援的消息代理産品插入應用程式。 然後,無需更改應用程式的代碼,即可交換消息代理。