無論您是開發新應用程式,還是正在提供高流量服務,都可以透過本指南的洞察資料和建議,瞭解如何透過 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)
重試放大效果:如果在重試失敗或逾時的要求時未採用指數型退避,就可能會在現有流量高峰之上,累積成重複的流量波。
流量模式突然改變:如果沒有漸進式增加等平滑因素,直接將新流量導向 FCM,或將流量跨區域轉移至 FCM,可能會導致流量尖峰。
前置配額符記用量:在配額時間窗口開始時耗盡所有配額符記,而非將要求平均分散至各個配額時間窗口,會造成開關式震盪,這類情況很難以負載平衡的方式來解決。
特殊活動:假日 (除夕) 或體育賽事 (FIFA 世界盃) 期間的流量激增。
透過「平滑曲線」解決流量尖峰問題
本節將說明如何盡可能平滑流量尖峰,也就是「平滑曲線」的策略。
僅在適當的用途中使用 FCM
在某些情況下,使用 FCM 傳送通知並非必要或適當。
舉例來說,如果是行事曆事件通知,您可以在應用程式中排定本機工作,以便在適當時間顯示通知,而非透過應用程式伺服器傳送通知。將 FCM 訊息限制為日曆同步處理。
避免尖峰
其中一個擴充反模式是盡可能快速傳送 FCM 通知,而不是套用伺服器端節流。如下所示:
- 是否所有客戶都需要在 1 分鐘內收到相同的通知?舉例來說,5 分鐘的送達時間是否仍能滿足你的業務需求?
- 您能否根據優先順序區隔客戶,以便平滑尖峰流量?
- 您可以提前排定通知嗎?
盡可能:避免採用會立即耗盡 FCM 傳送配額的策略,只在權杖桶重新填滿時重複執行這類模式。這種存取模式會導致 FCM 及其依附系統的負載平衡問題。盡可能逐步增加流量。至少在 60 秒的時間範圍內,從 0 逐步增加至每秒要求數上限。建議使用較長的回溯期,以提高 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。
- 推出計畫可讓相關人員瞭解預期情況。在某些情況下 (詳見下文),建議您提前與 Firebase 雲端通訊團隊分享推行計畫,以免發生意外。
- 復原計畫可讓您考量意外狀況,並準備機制,以便快速且安全地從意外失敗中復原。
- 漸進式變更有兩個層面:
- 「逐步」漸進式:步驟應為 1% -> 5% -> 10% -> 25% -> 50% -> 75% -> 100% 或更精細。進行「浸泡」(觀察系統在負載下的行為),每個步驟持續 1 天至 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。