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. 主題本身附加了兩個訂閱項目。分別是「訂閱項目 1」和「訂閱項目 2」。

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

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

  5. 訂閱項目 1 已連結至兩個訂閱者應用程式:「訂閱者 1」和「訂閱者 2」。這兩個訂閱者應用程式會收到主題中的部分訊息。在這個範例中,訂閱者 1 會收到訊息 B,而訂閱者 2 會收到訊息 A

  6. 訂閱項目 2 只會連結至名為「訂閱者 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 未在確認期限內收到確認訊息,系統可能會重複傳送訊息。舉例來說,訂閱者可能會在期限過後傳送確認訊息,或是確認訊息可能因暫時性網路問題而遺失。未確認的訊息會持續傳送,直到訊息發布後經過訊息保留時間為止。此時訊息就會過期。

  • 負向確認訊息 (NACK)。訂閱者對訊息執行 Nack 作業後,Pub/Sub 會根據預設重試設定立即重新傳送訊息,這項設定可以修改。如果訂閱者對無效訊息發出否定確認,或無法處理訊息,訂閱者可確保這些訊息不會遺失,並順利處理。您可以將 modifyAckDeadline 的值設為 0,藉此 NACK 訊息。

選擇 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. 建立或選擇可設定 Pub/Sub 的 Google Cloud 專案。

  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 呼叫時,請務必使用這個格式。

後續步驟