# Pub/Sub 是什麼？6 大常見名詞與訊息生命週期介紹

<header class="entry-header clr" id="bkmrk-pub%2Fsub-%E6%98%AF%E4%BB%80%E9%BA%BC%EF%BC%9F6-%E5%A4%A7%E5%B8%B8%E8%A6%8B%E5%90%8D%E8%A9%9E%E8%88%87">#  

</header><div id="bkmrk-">![Pub/Sub 是什麼？6 大常見名詞與訊息生命週期介紹](https://storage.googleapis.com/cloudace-tw-blog/1/2024/01/Pub-Sub-%E6%98%AF%E7%94%9A%E9%BA%BC%EF%BC%9F6-%E5%A4%A7%E5%B8%B8%E8%A6%8B%E5%90%8D%E8%A9%9E%E8%88%87%E8%A8%8A%E6%81%AF%E7%94%9F%E5%91%BD%E9%80%B1%E6%9C%9F%E4%BB%8B%E7%B4%B9.jpg)</div>文章段落

<div id="bkmrk-pub%2Fsub-%E6%98%AF%E4%BB%80%E9%BA%BC%EF%BC%9F-%E6%A6%82%E8%BF%B0%E8%88%87%E5%84%AA%E5%8B%A2%E4%BB%8B%E7%B4%B9"><div><label class="ez-toc-cssicon-toggle-label" for="ez-toc-cssicon-toggle-item-67ab0004b68b0"><svg class="list-377408" fill="none" height="20px" viewbox="0 0 24 24" width="20px" xmlns="http://www.w3.org/2000/svg"></svg><svg baseprofile="tiny" class="arrow-unsorted-368013" height="10px" version="1.2" viewbox="0 0 24 24" width="10px" xmlns="http://www.w3.org/2000/svg"></svg></label> [ ] <nav>- [Pub/Sub 是什麼？](https://blog.cloud-ace.tw/big-data/pub-sub-introduction/#PubSub_%E6%98%AF%E4%BB%80%E9%BA%BC%EF%BC%9F "Pub/Sub 是什麼？")
    - [概述與優勢介紹](https://blog.cloud-ace.tw/big-data/pub-sub-introduction/#%E6%A6%82%E8%BF%B0%E8%88%87%E5%84%AA%E5%8B%A2%E4%BB%8B%E7%B4%B9 "概述與優勢介紹")
    - [6 大常見名詞](https://blog.cloud-ace.tw/big-data/pub-sub-introduction/#6_%E5%A4%A7%E5%B8%B8%E8%A6%8B%E5%90%8D%E8%A9%9E "6 大常見名詞")
    - [訊息生命週期](https://blog.cloud-ace.tw/big-data/pub-sub-introduction/#%E8%A8%8A%E6%81%AF%E7%94%9F%E5%91%BD%E9%80%B1%E6%9C%9F "訊息生命週期")
- [ack / Retry 說明](https://blog.cloud-ace.tw/big-data/pub-sub-introduction/#ack_Retry_%E8%AA%AA%E6%98%8E "ack / Retry 說明")
    - [ack](https://blog.cloud-ace.tw/big-data/pub-sub-introduction/#ack "ack")
    - [Retry ](https://blog.cloud-ace.tw/big-data/pub-sub-introduction/#Retry "Retry ")
- [常見問題](https://blog.cloud-ace.tw/big-data/pub-sub-introduction/#%E5%B8%B8%E8%A6%8B%E5%95%8F%E9%A1%8C "常見問題")
- [結論](https://blog.cloud-ace.tw/big-data/pub-sub-introduction/#%E7%B5%90%E8%AB%96 "結論")

</nav></div><div data-url="https://blog.cloud-ace.tw/big-data/pub-sub-introduction/"></div><div data-elementor-id="8074" data-elementor-type="wp-post"><section class="elementor-section elementor-top-section elementor-element elementor-element-4327899a elementor-section-boxed elementor-section-height-default elementor-section-height-default" data-element_type="section" data-id="4327899a">**Google Cloud 的 Pub/Sub 可為不同的應用程式之間提供收發訊息的功能，以及每則訊息的接收狀態追蹤功能，確保任何規模的訊息皆可穩定地傳送，有效提升用戶服務的靈活與穩健性，這次就讓我們從零開始，完整解析 Pub/Sub 功能優勢、6 大常見名詞與訊息生命週期吧！**

<div><div><div data-element_type="column" data-id="49e848e"><div><div data-element_type="widget" data-id="6312c08" data-widget_type="text-editor.default"><div><div aria-hidden="true"> </div></div></div></div></div></div></div>## <span class="ez-toc-section" id="bkmrk--1"></span>**Pub/Sub 是什麼？**

### <span class="ez-toc-section" id="bkmrk--2"></span>**概述與優勢介紹**

Pub/Sub 是一種全球性訊息傳遞的服務，並具有高可用架構，可以在應用程式與服務間交換訊息。由 Publish 與 Subscribe 組成，運用了發佈及訂閱的概念讓訊息透過非同步的方式進行傳輸，只要您的服務可以處理訊息，Pub/Sub 就會持續傳送訊息，如果您 Subscription 下的所有 Subscriber 均無法處理訊息，Pub/Sub 會自動將您的訊息在默認的情況下保留 7 天 ( [該天數最高可以延長至 31 天](https://cloud.google.com/pubsub/docs/replay-overview?hl=zh-cn#message_retention) )。

另外在 Pub/Sub 中提供 3 種類型分別為：[多對一、多對多、一對多](https://cloud.google.com/pubsub/docs/pubsub-basics?hl=zh-cn#choose_a_publish_and_subscribe_pattern)，這 3 種類型可以讓使用者更靈活的處理訊息，讓服務可以高效運作。

### <span class="ez-toc-section" id="bkmrk--3"></span>**6 大常見名詞**

對 Pub/Sub 服務有初步了解之後就要針對 Pub/Sub 的服務進行更深入的探討，首先我們先來了解 Pub/Sub 的六個常見名詞及生命週期：

<div><div><div data-element_type="column" data-id="49e848e"><div><div data-element_type="widget" data-id="6312c08" data-widget_type="text-editor.default"><div>- Publisher （發布者）：創建訊息並將訊息傳送到指定主題上的服務/人。
- Subscription（訂閱）：為 Subscriber 的上游，主要負責將訊息傳給指定的 Subscriber。
- Subscriber（訂閱者）：訂閱特定主題的服務/人。
- Topic（主題）：處理 Publisher 傳送的訊息並將其儲存至 Google Cloud Storage （簡稱 GCS） 。
- Acknowledged（已確認 ）：簡稱「 ack 」主要用於確認訊息是否有被接收最少一次。
- Retry（重試）：若訊息處理失敗會進行 Retry 用來確保所有訊息都可以被處理的機制。

</div></div></div></div></div></div>### <span class="ez-toc-section" id="bkmrk--4"></span>訊息生命週期

訊息生命週期流程（1-5）說明：（1）將訊息傳到 Pub / Sub，（2）將訊息寫入儲存空間，（3）Pub / Sub 將訊息發布給該主題的所有訂閱，（4）訂閱將訊息發送到訂閱者，（5）訂閱者回覆「 ack 」確認已經收到此訊息，並將此訊息從 GCS 上刪除；至此生命週期結束。

[![pub/sub 訊息生命週期](https://storage.googleapis.com/cloudace-tw-blog/1/2024/01/%E7%94%9F%E5%91%BD%E9%80%B1%E6%9C%9F.png)](https://storage.googleapis.com/cloudace-tw-blog/1/2024/01/%E7%94%9F%E5%91%BD%E9%80%B1%E6%9C%9F.png)

截圖自：[Cloud Pub/Sub 產品頁](https://console.cloud.google.com/getting-started)  
©2023 Google

可以發現特別是在流程（5）需要回覆「 ack 」給 Pub / Sub，這是因為 Pub / Sub 的基礎架構為「 保證訂閱 」的方式設計，確保所有訊息可以被傳送一次，因此為了確保所有資料完整被 Subscriber 接收到，會特別要求 Subscriber 進行「 ack 」，若沒有即時進行「 ack 」您的訊息則會被丟入「 Retry 」中。

## <span class="ez-toc-section" id="bkmrk--5"></span>**ack / Retry 說明**

### <span class="ez-toc-section" id="bkmrk--6"></span>ack

**若訊息未 ack 有何影響**  
若訊息未 ack 在 Pub / Sub 的設計上就會進行 Retry requests 的操作，這個動作會將未在時間內「 ack 」的訊息重新排序，這可能會導致您的 Subscriber 無法即時找到相關的訊息，進而導致該訊息延遲的狀況發生。

**如何確認「 未 ack 」的訊息**  
可以透過「 [subscription/delivery\_latency\_health\_score](https://cloud.google.com/monitoring/api/metrics_gcp#pubsub/subscription/delivery_latency_health_score) 」、「 [subscription/ack\_latencies](https://cloud.google.com/monitoring/api/metrics_gcp#pubsub/subscription/ack_latencies) 」這兩個 Metric 來確認，其中「 subscription/delivery\_latency\_health\_score 」若有數值為「 0 」代表該 Topic 過去 10 分鐘內可能有[發生未正常處理的情況](https://cloud.google.com/pubsub/docs/monitoring?hl=zh-cn#delivery_latency_health)，比如：太晚進行「 ack 」、過去 10 分鐘內有 0.1% 的確認延遲時間超過 30 秒 … 等；另外也可以從下圖右下角的「 subscription/ack\_latencies 」看出延遲的時間。

[![0110-2_pub/sub_確認 “未 ack” 的訊息](https://storage.googleapis.com/cloudace-tw-blog/1/2024/01/%E7%A2%BA%E8%AA%8D-%E6%9C%AA-ack-%E7%9A%84%E8%A8%8A%E6%81%AF.png)](https://storage.googleapis.com/cloudace-tw-blog/1/2024/01/%E7%A2%BA%E8%AA%8D-%E6%9C%AA-ack-%E7%9A%84%E8%A8%8A%E6%81%AF.png)

截圖自：[Cloud Pub/Sub 產品頁](https://console.cloud.google.com/getting-started)  
©2023 Google

### <span class="ez-toc-section" id="bkmrk--7"></span>Retry 

**甚麼原因會出現 Retry？**  
Retry 是因為 Subscriber 未在時間內進行「 ack 」，這些未被「 ack 」的訊息會被 Pub / Sub 視為 Subscriber [無法處理訊息](https://cloud.google.com/pubsub/docs/handling-failures?hl=zh-cn#:~:text=%E5%A6%82%E6%9E%9C%20Pub/Sub%20%E5%B0%9D%E8%AF%95%E4%BC%A0%E9%80%81%E6%B6%88%E6%81%AF%EF%BC%8C%E4%BD%86%E8%AE%A2%E9%98%85%E8%80%85%E6%97%A0%E6%B3%95%E7%A1%AE%E8%AE%A4%E6%B6%88%E6%81%AF%EF%BC%8C%E5%88%99%20Pub/Sub%20%E4%BC%9A%E8%87%AA%E5%8A%A8%E5%B0%9D%E8%AF%95%E9%87%8D%E6%96%B0%E5%8F%91%E9%80%81%E6%B6%88%E6%81%AF%E3%80%82%E8%BF%99%E7%A7%8D%E9%87%8D%E6%96%B0%E6%8F%90%E4%BA%A4%E5%B0%9D%E8%AF%95%E7%A7%B0%E4%B8%BA%E8%AE%A2%E9%98%85%E9%87%8D%E8%AF%95%E6%94%BF%E7%AD%96%E3%80%82%E6%82%A8%E6%97%A0%E6%B3%95%E5%90%AF%E7%94%A8%E6%88%96%E5%81%9C%E7%94%A8%E6%AD%A4%E5%8A%9F%E8%83%BD%E3%80%82)，且基於 Pub / Sub 為保證訂閱的服務，因此會將這類的訊息進行 Retry；若所有 Subscriber 均無法處理訊息，Pub/Sub 會將訊息保存至 GCS 中。  
 **3 方法避免訊息被 Retry**  
如果服務處理速度跟不上 Pub / Sub 傳送的速度您可以透過以下方式進行修改：

<div><div><div data-element_type="column" data-id="49e848e"><div><div data-element_type="widget" data-id="6312c08" data-widget_type="text-editor.default"><div>- 提升服務的機器規格，讓您的服務可以即時處理 Pub / Sub 傳送的訊息。
- 可以透過延長「 ack 」時間來延後訊息被 Pub / Sub 視為無法處理。
- 可以加入[指數退避](https://cloud.google.com/pubsub/docs/handling-failures?hl=zh-cn#exponential_backoff)的方式讓訊息在第一次失敗後等待最短指數退避的時間並重新傳送。

</div></div></div></div></div></div>以上方法都可以盡量避免訊息被 Pub / Sub Retry，可以依照需求選擇最適合的方式。

## <span class="ez-toc-section" id="bkmrk--8"></span>常見問題

**若訊息被 Retry 如何減緩影響？**  
如果您的訊息是擁有順序性的話，您可以為在[訊息加入排序](https://cloud.google.com/pubsub/docs/ordering?hl=zh-cn)，可以讓來不及處理的訊息依照第一次的順序進行排序，可以避免您的服務請求順序出問題。

**如何延長 ack 時間？**  
預設的「 ack 」時間為 10 秒，若要延長可以透過修改 [modifyackDeadline](https://cloud.google.com/pubsub/docs/lease-management?hl=zh-cn#python:~:text=%E5%AE%A2%E6%88%B7%E7%AB%AF%E5%BA%93%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87%E5%AE%9A%E6%9C%9F%E5%8F%91%E5%87%BA%20modifyAckDeadline%20%E8%AF%B7%E6%B1%82) 來延長「 ack 」的時間，最高可將「 ack 」時間延長至 60 分鐘。

**若特定時間出現龐大流量該怎麼應對？**  
在 Pub / Sub 中提供使用 [Flow Control](https://cloud.google.com/pubsub/docs/flow-control?hl=zh-cn) 的方式針對瞬時流量進行處理。

## <span class="ez-toc-section" id="bkmrk--9"></span>結論

在設計服務流程時訊息處理是相當重要的一環，傳統地端可能需要自行架設、維護 Kafka、RabbitMQ… 這類型的服務費時又麻煩，不過 Google Cloud 提供 Pub/Sub 服務可以使用，並結合了保證訂閱、多對多、延時處理… 等優點，讓使用者可以減少管理訊息相關的時間，更專注在開發、優化服務上。

**這次介紹了 Pub/Sub 功能優勢， 6 大常見名詞與訊息生命週期。各位若有進一步的 Pub/Sub 操作疑問，歡迎[聯絡 Cloud Ace ](https://tw.cloud-ace.com/contact/)獲得更進一步的資訊。**

<div><div data-element_type="column" data-id="49e848e"><div><div data-element_type="widget" data-id="6312c08" data-widget_type="text-editor.default"><div><div aria-hidden="true"> </div></div></div></div></div></div></section></div></div>