大量傳送 FCM 訊息的最佳做法

無論是要開發新的應用程式,還是已經在執行高流量服務,本指南都會提供深入分析結果和建議,協助您瞭解如何使用 FCM 順利調度資源。這些概念和做法可協助您在傳送大量訊息時避免負面影響。

重要詞彙和概念

訊息要求:Firebase 雲端通訊訊息要求,可與「要求」、「訊息」或「查詢」互換使用。

每秒要求數 (RPS):這項指標會說明傳入 FCM 的要求比率,可與每秒查詢次數 (QPS) 交替使用。

配額符記、符記集區和補充:傳送訊息至 FCM HTTP v1 API 時,每個要求都會在特定時間範圍內消耗配額符記。這個視窗稱為「符記桶」,會在時間視窗結束時重新填滿。舉例來說,HTTP v1 API 會為每個 1 分鐘的符記集區分配 60 萬個配額符記,並在每個 1 分鐘的時間窗口結束時重新填滿。

伺服器端節流:當流量超過 FCM 服務的容量時,系統會拒絕超過服務容量的要求,以限制入站流量的速率。系統可能會傳回含有 retry-after 標頭的 429 錯誤回應,表示您應等待一段時間,再重試要求。

用戶端節流:當用戶端發現要求失敗、延遲時間過長或 429 錯誤時,應主動限制出口流量,以免加劇壅塞情形。

指數輪詢:重試錯誤時,請增加以指數方式遞增的時間延遲時間。例如:1 秒、2 秒、4 秒、8 秒、16 秒、32 秒。

抖動:避免以精確間隔重試要求。透過抖動,您可以透過隨機程序變更重試延遲時間,以便在一段時間內均勻分配 (例如:0.9 秒、2.3 秒、4.1 秒、8.5 秒、17.9 秒、34.7 秒)。

重試放大:如果在沒有指數輪詢/抖動機制下重試失敗的要求,這些要求通常會累積並增加目前的流量負載,可能會「放大」並加劇流量壅塞問題。

問題:流量尖峰

FCM 每秒可處理數百萬個要求 (RPS)。流量尖峰是導致系統壅塞、延遲問題和服務中斷的最大原因。

折線圖顯示不規則間隔的流量尖峰。

什麼是尖峰流量?

流量激增有幾種不同的類型。

每小時高峰:FCM 在前 30 秒到每小時 2 分鐘的流量超過兩倍。在半小時和四分鐘的時間點,也會出現類似的尖峰流量,但尖峰流量較小 (例如:00:15、00:30、00:45)

折線圖顯示半小時和 15 分鐘的尖峰趨勢。

重試放大效果如果在重試失敗或逾時的要求時未採用指數型退避,就可能會在現有流量高峰之上,累積成重複的流量波。

顯示高尖峰模式的折線圖。

流量模式突然改變:如果沒有漸進式增加等平滑因素,直接將新流量導向 FCM,或將流量跨區域轉移至 FCM,可能會導致流量尖峰。

折線圖顯示突然出現的尖峰。

前置配額符記用量:在配額時間窗口開始時耗盡所有配額符記,而非在配額時間窗口內平均分配要求,會造成開關式波動,這類情況很難以負載平衡的方式來解決。

折線圖顯示非常明顯的尖峰。

特殊活動:節日 (跨年夜) 或運動活動 (FIFA 世界盃) 期間的流量高峰。

這張折線圖顯示多次重複的尖峰。

透過「平滑曲線」解決流量尖峰問題

本節說明在可能的情況下,平緩流量高峰的策略,也就是「整併曲線」的策略。

僅在適當的用途中使用 FCM

在某些情況下,使用 FCM 傳送通知並非必要或適當。

舉例來說,如果是行事曆事件通知,您可以在應用程式中排定本機工作,以便在適當時間顯示通知,而非從應用程式伺服器傳送通知。將 FCM 訊息限制為日曆同步處理。

避免高點

其中一個擴充反模式是盡可能快速傳送 FCM 通知,而非套用伺服器端節流。如下所示:

  • 所有客戶是否需要在 1 分鐘內收到相同的通知?比方說,是否仍有 5 分鐘的送達時間,仍能滿足您的業務需求?
  • 是否可以根據優先順序區隔客戶,以便於高點過高峰?
  • 您是否可以提前安排通知?

盡可能:避免採用會立即耗盡 FCM 傳送配額的策略,只在權杖桶重新填滿時重複執行這類模式。這種存取模式會導致 FCM 及其依附系統的負載平衡問題。盡可能逐步增加流量。至少在 60 秒的時間範圍內,從 0 逐步增加至每秒要求數上限。建議使用較長的回溯期,以提高 RPS。

避免「每小時」的交通壅塞

盡可能:請避免在每個分鐘標記 :00、:15、:30 與 :45 分鐘之間傳送訊息。

實作伺服器端節流

實作伺服器端節流功能,監控及管理 FCM 的流量。

處理重試

雖然 FCM 努力維持高可用性,但有時某些要求會逾時或失敗。雖然原因各有不同,但下列最佳做法可改善重試行為,盡快傳送訊息,同時盡量減少對流量壅塞的影響。

逾時

請在重試前,為傳送要求設定至少 10 秒的逾時時間。大多數 FCM 內部遠端程序呼叫都會使用 10 秒的逾時值。

錯誤

  • 針對 400、401、403 和 404 錯誤:中止,且不要重試。
  • 針對 429 錯誤:等待 retry-after 標頭中設定的時間長度後,再重試。如果未設定 retry-after 標頭,預設值為 60 秒。
  • 如果是 500 錯誤:請以指數輪詢方式重試。

指數輪詢

為避免重試次數增加,請針對重試要求實作指數輪詢和抖動。舉例來說,Firebase Admin SDK 會實作指數輪詢。

以下是一些建議設定:

  • 最小間隔:不要立即透過 FCM 重試失敗的要求。請至少等待 10 秒,再重試失敗的要求。
  • 最大間隔:設定已過時的請求捨棄時間間隔上限,而非無限重試。

如果要求以指數輪詢方式持續重試,但在 60 分鐘後仍失敗,則表示該要求可能被誤歸類為可重試的錯誤,或是 FCM 發生服務中斷,重試可能會不小心使情況惡化。

建立推出和復原方案,以及逐步變更

如要進行大規模流量變更 (例如增加 FCM 的流量,或在各區域或網路之間轉移流量),請設計推出/回溯計畫,並逐步實施變更,以保護使用者、服務和 FCM。

  • 發布計畫可以滿足利害關係人期望。在某些情況下 (如下所述),建議您事先與 FCM 團隊分享推出計畫,以免發生意外情況。
  • 復原計畫可讓您考量意外狀況,並準備機制,以便快速且安全地從意外失敗中復原。
  • 逐步進行變更有兩個層面:
    • 「逐步」漸進式:步驟應為 1% -> 5% -> 10% -> 25% -> 50% -> 75% -> 100% 或更精細。進行「浸泡」(觀察系統在負載下的行為),每個步驟持續 1 天至 1 週。讓您在下一次「換機」前,先找出潛在問題
    • 逐步增加流量: 運用每個「步驟」增加流量時,讓流量分散於至少一小時。這可讓 FCM 負載平衡基礎架構適當調整新的流量,同時盡量減少可能發生的熱點和壅塞情形。

以下是假設情境,假設全球 500,000 個 RPS 從 FCM 舊版 HTTP API 遷移至 FCM HTTP v1 API:

步驟 逐步增加曝光策略
0 1% 的增加曝光量 在 1 小時內,從 0 到 5,000 RPS 順利提升至 FCM HTTP v1。
1 5% 適應期 在 2 小時內,從 5,000 到 25,000 RPS 順利提升。
2 10% 適應期 流暢度在 2 小時內從 25,000 至 50,000 RPS 順暢運作
3 25% 增加曝光量 在 3 小時內從 50,000 提升至 125,000 RPS
4 50% 的 ramp-up 在 6 小時內從 125,000 提升至 250,000 RPS
5 75% 的 ramp-up 在 6 小時內從 250,000 提升至 375,000 RPS
6 100% 適應期 在 6 小時內從 375,000 提升至 500,000 RPS

假設復原計畫:

  • 如果 95 個百分位數的延遲時間增加到超過 500 毫秒,或者任何步驟的錯誤率超過 1%,且持續超過一小時,請使用動態設定立即復原至上一個步驟。
  • 繼續回溯至先前的步驟,直到延遲時間和錯誤率恢復正常為止。

何時聯絡 FCM

如果發生下列任一情況,請透過 Firebase 支援團隊與 FCM 聯絡:

  • 預設配額不再符合您的用途
  • 您在 3 個月的時間內變更傳送模式,且全球傳送率達到 100,000 RPS,或在某個大洲達到 30,000 RPS。