無論是要開發新的應用程式,還是已經在執行高流量服務,本指南都會提供深入分析結果和建議,協助您瞭解如何使用 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 分鐘之間傳送訊息。
實作伺服器端節流
實作伺服器端節流功能,監控及管理 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。