Pub/Sub 服務簡介

Pub/Sub 是發布/訂閱 (Pub/Sub) 服務,這類訊息服務會將訊息傳送者與訊息接收者分離。Pub/Sub 服務中包含幾個重要概念,我們會在下圖中說明這些概念。

圖表顯示 Pub/Sub 服務的不同元件,以及這些元件彼此之間的連結方式。
圖 1 兩個發布端用戶端將兩則不同的訊息傳送至相同的 Pub/Sub 主題。

以下是 Pub/Sub 服務的元件:

  • 發布者 (又稱為供應者):建立訊息,並將訊息傳送 (發布) 至指定主題的通訊服務。

  • 「訊息」:在服務中移動的資料。

  • 「主題」:一種具名實體,代表訊息來源。

  • 結構定義:一種具名實體,用於管制 Pub/Sub 訊息的資料格式。

  • 「訂閱項目」:一種具名實體,代表接收特定主題相關訊息的意願。

  • 訂閱端 (又稱為取用端):接收指定訂閱項目的訊息。

以下程序說明 Pub/Sub 服務的工作流程:

  1. 兩個發布端應用程式 (發布端 1發布端 2) 將訊息傳送至單一 Pub/Sub 主題。發布者 1 傳送訊息 A發布者 2 傳送訊息 B

  2. 主題本身已連結至兩個訂閱項目。分別是 Subscription 1Subscription 2

  3. 主題也會附加至結構定義。

  4. 每個訂閱項目都會從主題接收 AB 訊息的副本。

  5. Subscription 1 已連結至兩個訂閱應用程式:Subscriber 1Subscriber 2。兩個訂閱者應用程式會接收主題的訊息子集。在這個範例中,訂閱者 1 會收到主題中的訊息 B,而訂閱者 2 會收到訊息 A

  6. Subscription 2 只連結至名為 Subscriber 3 的單一訂閱者應用程式。因此,訂閱者 3 會收到來自主題的所有訊息。

訊息的生命週期

假設單一發布者用戶端已連結至主題。這個主題有一個連結的訂閱項目。單一訂閱者與訂閱方案相關聯。

圖表顯示訊息在 Pub/Sub 中的流動方式。
圖 2 訊息透過 Pub/Sub 從發布端用戶端流向訂閱端用戶端。

以下步驟說明訊息在 Pub/Sub 中的流程:

  1. 發布端應用程式將訊息傳送至 Pub/Sub 主題。

  2. 將訊息寫入儲存空間。

  3. 除了將訊息寫入儲存空間,Pub/Sub 也會將訊息傳送至主題的所有附加訂閱項目。

    在本範例中,這是單一訂閱。

  4. 訂閱項目會將訊息傳送至附加的訂閱者應用程式。

  5. 訂閱者會向 Pub/Sub 傳送確認訊息,表示已處理訊息。

    每個訂閱項目至少有一位訂閱者確認訊息後,Pub/Sub 就會從儲存空間中刪除訊息。

Pub/Sub 中的訊息狀態

當訂閱者未完成訊息時,Pub/Sub 不會嘗試將訊息提交給同一個訂閱項目的任何其他訂閱者。訂閱者應該在可設定的限制時間內 (又稱為 ackDeadline) 確認未完成的訊息。一旦超過期限,系統就不會再將這則訊息視為未完成的項目,而可再次提交訊息。

Pub/Sub 服務中的訊息可能有三種狀態:

  • 已確認的訊息 (已確認)。訂閱者應用程式處理主題傳送至訂閱項目的訊息後,會將確認訊息傳回至 Pub/Sub。如果主題中的所有訂閱項目都已確認訊息,系統會從發布訊息來源和儲存空間中非同步刪除訊息。

  • 未確認的訊息 (未確認)。如果 Pub/Sub 未在確認期限內收到確認,訊息可能會傳送多次。舉例來說,訂閱者可能會在期限過期後傳送確認訊息,或是因暫時性網路問題而導致確認訊息遺失。未確認的訊息會持續傳送,直到訊息發布後的訊息保留時間到期為止。此時,訊息就會失效。

  • 已拒絕確認的訊息 (nacked)。訂閱者如果取消訊息,Pub/Sub 就會立即重新傳送該訊息。當訂閱者將無效訊息標示為 nack,或無法處理訊息時,訂閱者可確保這些訊息不會遺失,並最終順利處理。您可以使用 modifyAckDeadline 並將值設為 0,藉此拒絕訊息。

選擇 Pub/Sub 發布和訂閱模式

如果有多個 Pub/Sub 發布者和訂閱者用戶端,您也必須選擇要設定的發布和訂閱架構類型。

圖表顯示不同的發布和訂閱模式。
圖 3 發布者訂閱者關係可以是多對一 (集中傳遞)、多對多 (負載平衡) 和一對多 (擴散傳遞)。

部分支援的 Pub/Sub 發布/訂閱模式包括:

  • 集中傳遞 (多對一)。在這個例子中,多個發布者應用程式會將訊息發布至單一主題。這個單一主題會連結至單一訂閱項目。而訂閱項目則會連結至單一訂閱者應用程式,該應用程式會取得主題發布的所有訊息。

  • 負載平衡 (多對多)。在這個範例中,單一或多個發布者應用程式會將訊息發布至單一主題。這個單一主題會附加至單一訂閱項目,而該訂閱項目又會連結至多個訂閱者應用程式。每個訂閱者應用程式都會收到部分已發布訊息,且沒有兩個訂閱者應用程式會收到相同的訊息子集。在這個負載平衡案例中,您會使用多個訂閱者來處理大量訊息。如果需要支援更多訊息,您可以新增更多訂閱者,讓他們透過同一個訂閱項目接收訊息。

  • 扇形展開 (一對多)。在這個範例中,單一或多個發布者應用程式會向單一主題發布訊息。這個單一主題會連結至多個訂閱項目。每個訂閱項目都會連結至單一訂閱者應用程式。每個訂閱者應用程式都會從主題取得相同的發布訊息組合。如果主題有多個訂閱項目,則每則訊息都必須傳送給代表各訂閱項目接收訊息的訂閱者。如果您需要對同一組訊息執行不同的資料作業,扇形展開是個不錯的選擇。您也可以為每個訂閱項目附加多個訂閱者,並為每位訂閱者取得負載平衡的訊息子集。

選擇 Pub/Sub 設定選項

您可以使用下列任一選項設定 Pub/Sub 環境:

  • Google Cloud 控制台
  • Google Cloud CLI
  • Cloud 用戶端程式庫 (高階用戶端程式庫)
  • REST 和 RPC API (低階用戶端程式庫)

您選擇的 Pub/Sub 設定選項取決於您的用途。

如果您是 Google Cloud 控制台的新手,且想測試 Pub/Sub,請使用控制台或 gcloud CLI

如果您需要高處理量和低延遲,且希望盡量減少作業負擔和處理成本,建議您使用高階用戶端程式庫。根據預設,高階用戶端程式庫會使用 StreamingPull API。高階用戶端程式庫包含預先建構的函式和類別,可處理底層 API 呼叫,以便進行驗證、最佳化傳輸量和延遲時間、訊息格式設定和其他功能。

低階用戶端程式庫是自動產生的 gRPC 程式庫,會在您直接使用服務 API 時發揮作用。

以下是使用用戶端程式庫的最佳做法:

  • 選擇正確的用戶端程式庫語言。Pub/Sub 用戶端程式庫的效能會因語言而異。舉例來說,Java 用戶端程式庫在垂直擴充方面比 Python 用戶端程式庫更有效,而且可以處理更多輸送量。就處理發布或訂閱負載所需的運算資源而言,Java、C++ 和 Go 是更有效率的語言。

  • 使用最新版本的用戶端程式庫。Pub/Sub 用戶端程式庫會持續更新,加入新功能和修正錯誤。請確認您使用的是所用語言的最新版用戶端程式庫。

  • 重複使用發布商用戶端。發布訊息時,重複使用相同的發布者用戶端會比為每項發布要求建立新的發布者用戶端更有效率。這是因為建立新的發布商用戶端後,首次發布要求需要一些時間才能建立授權連線。在 Node 等不含明確發布端用戶端的某些語言中,請重複使用呼叫發布方法的物件。例如,在 Node 中儲存及重複使用主題物件。

如何設定 Pub/Sub

以下是設定 Pub/Sub 的頂層步驟:

  1. 建立或選擇 Google Cloud 專案,以便設定 Pub/Sub。

  2. 啟用 Pub/Sub API。

  3. 取得執行 Pub/Sub 所需的角色和權限。

  4. 建立主題。

  5. 如果訊息結構至關重要,請為訊息定義結構定義。

  6. 將結構定義附加至主題。

  7. 設定可將訊息發布至主題的發布端用戶端。

  8. 視需要設定進階發布選項,例如流程控管、批次訊息和並行控管。

  9. 請根據您想要接收訊息的方式選擇訂閱類型。

  10. 為所選主題建立訂閱項目。

  11. 設定可接收訂閱項目訊息的訂閱端用戶端。

  12. 如有需要,請設定進階郵件傳送選項,例如確切一次傳送、租用管理、有序傳送和流程控制。

  13. 開始透過發布端用戶端將訊息發布至主題。

  14. 同時設定訂閱端用戶端,以便接收及處理這些訊息。

主題、訂閱項目、結構定義或快照的命名規範

Pub/Sub 資源名稱是主題、訂閱、結構定義或快照等 Pub/Sub 資源的專屬識別名稱。資源名稱必須符合以下格式:

projects/project-identifier/collection/ID

  • project-identifier:必須是專案 ID 或專案編號,可在 Google Cloud 控制台找到。例如 my-cool-project 是專案 ID。123456789123 是專案編號。

  • collection:必須是 topicssubscriptionsschemassnapshots 之一。

  • ID:必須符合下列規範:

    • 開頭不是字串 goog
    • 以英文字母開頭
    • 由 3 到 255 個字元組成
    • 只能包含下列字元:英文字母 [A-Za-z]、數字 [0-9]、連字號 -、底線 _、半形句號 .、波浪號 ~、加號 + 和百分比符號 %

    您可以在資源名稱中使用上述清單中的特殊字元,不必進行網址編碼。不過,您必須確保在網址中使用其他特殊字元時,這些字元已正確編碼或解碼。例如,mi-tópico 是無效的ID。不過,mi-t%C3%B3pico 是有效的。您在發出 REST 呼叫時,必須使用這個格式。

後續步驟