本文提供一些常見的 Pub/Sub 提取訂閱疑難排解提示。如要進一步瞭解提取訂閱項目,請參閱提取訂閱者指南。
如要有效監控 Pub/Sub 訂閱項目,建議您先查看傳遞延遲時間健康狀態分數 (subscription/delivery_latency_health_score),確認哪些因素可能導致延遲時間異常或增加。
最舊未確認訊息的存在時間持續增加
oldest_unacked_message_age
是用於監控 Pub/Sub 訂閱項目運作狀態的重要指標。這個屬性會以秒為單位,測量訂閱項目待處理訊息中,最舊的訊息尚未獲得訂閱者確認 (已確認) 的時間。這項指標可提供潛在的處理延遲或瓶頸相關實用洞察資料。
監控訊息積壓情形,確保訊息能及時且有效率地處理。追蹤最舊的未確認訊息存在時間,即可主動找出消費者落後的情況。這項做法可讓您及早介入,解決效能降低的潛在問題。
您可以調查的常見積壓問題包括:
用戶端設定問題
如果 oldest_unacked_message_age
和 num_undelivered_messages
指標同時增加,可能表示訂閱者無法跟上訊息量。在這種情況下,請將調查重點放在訂閱者元件上:
用戶端健康狀況:分析代管訂閱者用戶端的電腦上資源使用率,例如 CPU、記憶體和網路頻寬。找出可能影響處理效率的壓力點。
用戶端程式碼:查看最近的程式碼變更,並檢查錯誤記錄。訂閱者程式碼中的錯誤或效率不佳,可能會嚴重影響訊息處理率。請注意,特定郵件可能會發生問題。舉例來說,多則訊息可能需要同時存取資料庫中的同一列。這可能會導致爭用和高延遲。
配額限制:請確認您並未超出任何 Pub/Sub 配額或代管服務的限制。如果訂閱者在 Google Cloud中代管,請查看 Compute Engine 或 GKE 資源配額,以防出現瓶頸。
訂閱者未確認訊息
當訂閱者拒絕確認 (nack) 訊息時,會向 Pub/Sub 發出訊號,表示無法順利處理訊息。接著,Pub/Sub 會嘗試重新傳送相同的訊息。重複傳送訊息的 nack 會導致重複傳送,並可能導致訊息傳送延遲。
請注意,即使您已將訊息設為已處理,下次拉取時也不保證會擷取其他訊息。Pub/Sub 的重送政策可能會繼續在傳送新訊息之前,先傳送裸露訊息。因此,請勿依賴 nack 篩除或略過特定訊息。請改為設定重試政策,最好是指數回退,以便針對個別訊息進行回退,這些訊息可能稍後可供處理,但需要較長的時間才能重新傳送。
如果您需要刻意略過特定訊息,建議您採用回應方式,即使您不會處理這些訊息也一樣。這樣一來,系統就會將這些資源從訂閱項目中移除,避免不必要的重複提交,並減少資源用量。無論是否有意,未確認訊息都會導致待處理工作和重複傳送問題。
傳送延遲時間長
Pub/Sub 中的傳送延遲時間,是指發布端傳送訊息到達訂閱端所需的時間。後續章節將說明導致高提交延遲的可能原因。
訂閱者人數不足
對於使用 StreamingPull 的用戶端,為了持續維持低延遲,請為訂閱項目保留多個開放的 StreamingPull 連線。如果沒有有效的訂閱者連線,Pub/Sub 就無法即時傳送訊息。單一串流可能會成為單點故障,導致延遲風險增加。subscription/open_streaming_pulls
指標可讓您瞭解有效串流連線的數量。這樣一來,您就能確保持續有足夠的串流來處理傳入的訊息。
對於使用單一提取作業的用戶端,為了持續達到低延遲,請為訂閱項目保留多個未解決的提取要求。不常出現的要求可能會導致待處理訊息累積,並增加延遲時間。這有助於盡量縮短連線中斷時間,並改善提交延遲時間。
如果您需要高處理量和低延遲,且作業負擔和處理成本極低,建議使用高階用戶端程式庫。根據預設,高階用戶端程式庫會使用 StreamingPull API,因為這通常是減少延遲時間的較佳選擇。高階用戶端程式庫包含預先建構的函式和類別,可處理底層 API 呼叫,以便進行驗證、最佳化傳輸量和延遲時間、訊息格式設定,以及其他功能。
用戶端設定問題
請參閱「用戶端設定問題」。
待處理工作數量偏高
請注意,Pub/Sub 訂閱項目中未確認訊息的待處理訊息會自然增加端對端延遲時間,因為訊息不會立即由訂閱者處理。
排序鍵和僅傳送一次
排序鍵和一次傳送一筆資料的功能都非常實用,但需要在 Pub/Sub 中進行額外協調,才能確保正確傳送。這項協調作業可能會降低可用性,並增加延遲時間。雖然在穩定狀態下差異不大,但任何必要的協調步驟都可能導致延遲時間暫時增加或錯誤率上升。如果啟用排序功能,系統會先確認先前傳送的相同排序鍵訊息,再傳送含有排序鍵的訊息。
請考量應用程式是否絕對需要訊息排序或確切一次傳送。如果您最重視低延遲,請盡量減少使用這些功能,以便減少訊息處理延遲時間。
訊息大小增加
訊息大小突然增加,可能會增加 Pub/Sub 與用戶端之間的傳輸時間,並延長用戶端端處理訊息的時間。
如果您發現傳送延遲時間增加,可以使用 topic/message_sizes
指標,並按 topic_id
分組來查看訊息大小。將訊息大小的任何尖峰與觀察到的效能問題做連結。
缺少訊息
如果您懷疑訊息無法順利傳送給訂閱者,下列其中一個原因可能是影響因素。
在有多個使用者的 Pub/Sub 訂閱中分配訊息
在 Pub/Sub 中,訊息可能會不均勻地分散到各個使用者。這是因為 Pub/Sub 會將訊息分發給有效的消費者,以提高效率。有時,單一消費者收到的訊息可能比預期少,或是與其他消費者收到的訊息不同。
請注意,客戶可能已收到未讀取的訊息,且未讀取的訊息積壓未讀,並不代表您會在下次拉取要求中收到這些訊息。請注意,使用者可能會在 Google Cloud 控制台或 Google Cloud CLI 中使用 pull 功能,或是在本機執行自訂訂閱者來查看訊息。
對於一元提取用戶端,您可能會發現某些提取要求傳回零個訊息。如「訂閱者不足」一節所述,建議您保留多個待處理的拉取要求,因為某些要求可能會傳回的訊息數量少於設定的上限,甚至傳回零個訊息。
如果您懷疑有上述行為,請調查是否有其他消費者同時連接至訂閱項目,並進行檢查。
依訂閱項目篩選
檢查訂閱項目是否附加篩選器。這樣一來,您就只會收到符合篩選條件的訊息。Pub/Sub 服務會自動確認不符合篩選條件的訊息。請考量篩選器對積壓指標的影響。
使用 returnImmediately
選項
如果您的用戶端使用一元式 Pull,請檢查 returnImmediately
欄位是否設為 true。這是已淘汰的欄位,可讓 Pub/Sub 服務立即回應拉取要求,即使該要求未傳回任何訊息也一樣。這可能會導致即使有待處理的訊息,拉取要求也會傳回 0 個訊息。
處理重複項目
當訂閱端無法在確認期限內確認訊息時,Pub/Sub 中就經常會發生訊息重複的情況。這會導致系統重新傳送郵件,造成重複傳送的錯覺。您可以使用 subscription/expired_ack_deadlines_count
指標,評估訂閱者錯過確認期限的比率。進一步瞭解如何監控確認期限到期時間。
為了減少重複比率,請延長訊息期限。
- 用戶端程式庫會自動處理期限延長,但您可設定的最大延長期限有預設限制。
- 如果您正建構自己的用戶端程式庫,請使用
modifyAckDeadline
方法延長確認期限。
如果訊息的拉取速度比處理和確認速度快,部分訊息可能會過期,需要延長截止期限。不過,如果訂閱者仍無法在期限內完成作業,多次延長期限最終仍會失敗。在最糟糕的情況下,這可能會導致訂閱者出現重複項目,導致積壓情況惡化。讓重複項目到期,然後產生新的重複項目。
為避免訂閱者收到過多訊息,請減少訂閱者每次擷取的訊息數量。這樣一來,訂閱者在期限內處理的郵件就會減少。訊息到期和重新傳送的次數會減少。
如要減少訂閱者每次拉取的訊息數量,您需要在訂閱者的流量控制設定中減少未處理訊息的最大數量。沒有一體適用的值,因此您必須根據總處理量和訂閱者容量調整未送出訊息上限。請注意,每個應用程式處理訊息的方式不同,回應訊息所需的時間也不同。
強制重試
如要強制 Pub/Sub 重試訊息,請傳送 nack
要求。如果您未使用高階用戶端程式庫,請傳送 modifyAckDeadline
要求,並將 ackDeadlineSeconds
設為 0。
排序鍵
當 Pub/Sub 重新傳送含有排序鍵的訊息時,也會重新傳送所有含有相同排序鍵的後續訊息,即使這些訊息先前已確認接收也一樣。這是為了保留序列的順序。不過,我們無法嚴格保證,只有在序列中先前訊息成功傳送後,才會傳送相關訊息。
訂閱者正在要求訊息
請參閱「訂閱者正在要求訊息」。
排解 StreamingPull 訂閱問題
要求延遲時間指標與端對端提交延遲時間的關係
針對 StreamingPull,serviceruntime.googleapis.com/api/request_latencies 指標代表串流開啟的時間。這項指標無法用於判斷端對端提交延遲時間。
請使用傳送延遲時間健康狀態分數,而非要求延遲時間指標,檢查哪些因素導致端對端傳送延遲時間增加。
StreamingPull 連線關閉,且狀態為「非 OK」
StreamingPull 串流一律會以非「OK」狀態關閉。與一元 RPC 的錯誤狀態不同,StreamingPull 的這項狀態只是表示串流已中斷。要求並未失敗。因此,雖然 StreamingPull API 的錯誤率可能會高達 100%,但這項行為是設計上的考量。
由於 StreamingPull 串流一律會在發生錯誤時關閉,因此在診斷錯誤時檢查串流終止指標並無幫助。請改為專注於 StreamingPull 回應指標 subscription/streaming_pull_response_count
,並按 response_code
或 response_class
分組。
請留意以下錯誤:
如果訂閱待處理項目中含有使用停用的 Cloud KMS 金鑰加密的訊息,可能會發生前置條件失敗錯誤。如要繼續拉取,請恢復金鑰的存取權。
當 Pub/Sub 無法處理要求時,可能會發生無法使用錯誤。這很可能是暫時性問題,用戶端程式庫會重試要求。如果您使用的是用戶端程式庫,則無須採取任何行動。
當訂閱項目遭到刪除,或從未存在時,就會發生找不到錯誤。如果您提供無效的訂閱路徑,就會發生後一種情況。