大規模發送 FCM 訊息時的最佳實踐

無論您是正在開發新應用程式還是已經在運行高流量服務,您都可以從本指南中有關如何使用 FCM 順利擴展的見解和建議中受益。當您需要發送大量訊息時,這些概念和實踐可以幫助您避免負面影響。

關鍵術語和概念

訊息請求:FCM訊息請求;與「請求」、「訊息」或「查詢」互換使用。

每秒請求數 (RPS) :描述 FCM 傳入請求速率的指標;與每秒查詢數 (QPS) 互換使用。

配額令牌、令牌桶和補充:根據 FCM HTTP v1 API 發送訊息時,每個請求都會在給定時間視窗內消耗分配的配額令牌。此視窗稱為“令牌桶”,在時間視窗結束時重新填滿。例如:HTTP v1 API 為每個 1 分鐘令牌桶分配 600K 配額令牌,並在每個 1 分鐘視窗結束時重新填滿。

伺服器端限制:當流量超過 FCM 服務的容量時,超出服務容量的請求將被拒絕,以對入口流量進行速率限制。可能會傳回帶有retry-after標頭的429錯誤回應,以指示您應該在重試請求之前等待給定的時間段。

客戶端限制:當客戶端觀察到請求失敗、高延遲或429錯誤時,它們應該主動對出口流量進行速率限制,以避免加劇擁塞。

指數退避:重試錯誤時,增加指數增加的時間延遲。例如:1秒、2秒、4秒、8秒、16秒、32秒。

抖動:避免以精確的時間間隔重試請求。透過抖動,您可以透過隨機過程改變重試延遲,使它們隨時間均勻分佈(例如:0.9s、2.3s、4.1s、8.5s、17.9s、34.7s)。

重試放大:當在沒有指數退避/抖動的情況下重試失敗的請求時,它們通常會累積並增加持續的流量負載,可能會「放大」並加劇流量擁塞問題。

問題:流量激增

FCM 每秒處理數百萬個請求 (RPS)。造成系統擁塞、延遲問題和中斷的最大因素是流量峰值。

顯示流量以不規則間隔激增的折線圖。

什麼是高峰流量?

有幾種不同類型的流量峰值。

整點高峰:FCM 在每小時的前 30 秒到 2 分鐘內收到雙倍以上的流量。類似的,儘管較小,在半小時和刻鐘標記處也觀察到峰值(示例:00:15、00:30、00:45)

顯示每半小時和每刻鐘峰值趨勢的折線圖。

重試放大在沒有指數退避的情況下重試失敗或逾時的請求可能會在現有流量峰值之上累積成重複的流量波。

顯示增加尖峰模式的折線圖。

流量模式突然變化:將新流量引導到 FCM 或跨區域將流量轉移到 FCM,而沒有平滑因素(例如逐漸增加)可能會導致峰值。

顯示突然峰值的折線圖。

提前加載配額令牌使用:在配額視窗開始時耗盡所有配額令牌,而不是在配額視窗中均勻分佈請求,將產生開關振盪,這對於負載平衡來說是困難且昂貴的。

顯示非常急劇的峰值的折線圖。

特殊活動:假日(除夕夜)或體育賽事( FIFA 世界盃)期間流量高峰。

顯示多個重複峰值的折線圖。

透過「拉平曲線」來緩解流量高峰

本節介紹了盡可能平滑流量峰值的策略—「拉平曲線」的策略。

僅將 FCM 用於適當的用例

在某些用例中,使用 FCM 來傳送通知是不必要或不合適的。

例如,對於日曆事件通知,您可以在應用程式中安排本機任務以在適當的時間顯示通知,而不是從應用程式伺服器發送通知。將 FCM 訊息限制為日曆同步。

避免尖峰

一種擴展反模式是在系統允許的情況下盡快發送 FCM 通知,而不是應用伺服器端限制。考慮以下:

  • 您的所有客戶是否都需要在 1 分鐘內收到相同的通知?例如,5 分鐘的交付窗口是否仍能滿足您的業務需求?
  • 能否根據優先順序對您的客戶進行細分以平滑高峰?
  • 您的通知可以提前安排嗎?

盡可能:避免導致立即耗盡 FCM 發送配額的策略,僅在令牌桶重新填充後才重複該模式。這種存取模式為 FCM 及其依賴系統帶來了負載平衡問題。盡可能逐漸增加流量。至少,在 60 秒的時間窗口內從 0 斜坡到最大 RPS。為了獲得更高的 RPS,首選更長的視窗。

避免「準時」交通

盡可能:避免在 :00、:15、:30 和 :45 分鐘標記的 2 分鐘視窗內發送訊息。

實作伺服器端節流

實施伺服器端限制來監控和管理流向 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% 提升在一個小時內從 0 RPS 平穩提升到 5,000 RPS 到 FCM HTTP v1。
1 5% 的提升在 2 小時內從 5,000 RPS 平穩提升至 25,000 RPS。
2 10% 提升在 2 小時內從 25,000 RPS 平穩提升至 50,000 RPS
3 25% 的提升3 小時內從 50,000 RPS 提升至 125,000 RPS
4 50% 提升6 小時內從 125,000 RPS 提升至 250,000 RPS
5 75% 提升6 小時內從 250,000 RPS 提升至 375,000 RPS
6 100% 提升6 小時內從 375,000 RPS 提升至 500,000 RPS

假設的回滾計劃:

  • 如果 95% 延遲增加到大於 500 毫秒,或任何步驟錯誤率超過 1% 超過 1 小時,請使用動態設定立即回滾到上一個步驟。
  • 繼續回滾到之前的步驟,直到延遲和錯誤率恢復到正常水平。

何時聯絡 FCM

如果存在以下任何情況,請透過Firebase 支援聯絡 FCM:

  • 預設配額不再滿足您的用例
  • 您將在 3 個月的時間內以全球 100,000 RPS 或大陸 30,000 RPS 的規模更改發送模式。