대규모 FCM 메시지 전송 시 권장사항

초기 앱을 개발 중이든 이미 트래픽이 많은 서비스를 실행 중이든 FCM을 통해 원활하게 확장하는 방법에 대한 이 가이드의 유용한 정보와 권장사항을 활용할 수 있습니다. 이러한 개념과 권장사항을 따르면 대량의 메시지를 보내야 할 때 부정적인 영향을 방지할 수 있습니다.

주요 용어 및 개념

메시지 요청: FCM 메시지 요청입니다. '요청', '메시지', '쿼리'와 같은 의미로 사용됩니다.

초당 요청 수(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분 사이에 2배 이상의 트래픽을 수신합니다. 비교적 덜하지만 비슷한 급증이 30분 및 15분마다(예: 00:15, 00:30, 00:45) 관찰됩니다.

30분 및 15분 단위로 급증하는 추세를 보여주는 선 차트입니다.

재시도 증폭: 지수 백오프 없이 실패했거나 시간이 초과된 요청을 재시도하면 기존의 최대 트래픽에 반복적인 트래픽이 누적될 수 있습니다.

증가하는 급증 패턴을 보여주는 선 차트입니다.

갑작스러운 트래픽 패턴 변경: 점진적인 증가와 같은 완화 요소 없이 새 트래픽을 FCM으로 전달하거나 트래픽을 여러 리전의 FCM으로 이동하면 급증이 발생할 수 있습니다.

급격한 하나의 상승을 보여주는 선 차트입니다.

프런트로드 할당량 토큰 사용: 요청을 할당량 기간 전체에 고르게 분산하는 대신 할당량 기간 초반에 모든 할당량 토큰을 소진하면 부하를 분산하기 어렵고 비용이 많이 드는 온오프 진동이 발생합니다.

매우 급격한 상승을 보여주는 선 차트입니다.

특별 이벤트: 휴일(새해 전야)이나 스포츠 이벤트(FIFA 월드컵) 중에 트래픽이 급증합니다.

급상승 구간이 여러 개 있는 선 차트입니다.

'곡선 평탄화'를 통해 트래픽 급증 해결

이 섹션에서는 가능한 경우 트래픽 급증을 완화하기 위한 전략인 '곡선 평탄화'에 대해 설명합니다.

적절한 사용 사례에만 FCM 사용

FCM을 사용하여 알림을 전송하는 것이 불필요하거나 적절하지 않은 사용 사례가 있습니다.

예를 들어 캘린더 일정 알림의 경우 앱 서버에서 알림을 전송하는 대신 적절한 시간에 알림을 표시하도록 앱에서 로컬 태스크를 예약할 수 있습니다. FCM 메시지를 캘린더 동기화로 제한합니다.

트래픽 급증 방지

확장 안티패턴 중 하나는 서버 측 제한을 적용하는 대신 시스템에서 허용하는 한 빨리 FCM 알림을 보내는 것입니다. 다음 사항을 고려하세요.

  • 모든 고객이 1분 이내에 동일한 알림을 받아야 하나요? 예를 들어 5분의 전송 시간도 비즈니스 요구사항을 충족할 수 있나요?
  • 급증을 완화하기 위해 우선순위에 따라 고객을 분류할 수 있나요?
  • 알림을 미리 예약할 수 있나요?

가능한 경우: FCM 전송 할당량이 즉시 소진되는 전략은 피하세요. 토큰 버킷이 다시 채워지는 즉시 패턴이 반복됩니다. 이 액세스 패턴은 FCM과 종속 시스템에 부하 분산 문제를 일으킵니다. 트래픽을 최대한 점진적으로 늘립니다. 최소한 60초 동안 0에서 최대 RPS까지 늘립니다. 높은 RPS에는 더 긴 기간을 권장합니다.

'정시' 트래픽 방지

가능한 경우: 정각, 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% 증가 한 시간 동안 FCM HTTP v1로 0에서 5,000RPS로 분산하여 늘립니다.
1 5% 증가 2시간 동안 5,000RPS에서 25,000RPS로 분산하여 늘립니다.
2 10% 증가 2시간 동안 25,000RPS에서 50,000RPS로 분산하여 늘립니다.
3 25% 증가 3시간 동안 50,000RPS에서 125,000RPS로 분산하여 늘립니다.
4 50% 증가 6시간 동안 125,000RPS에서 250,000RPS로 분산하여 늘립니다.
5 75% 증가 6시간 동안 250,000RPS에서 375,000RPS로 분산하여 늘립니다.
6 100% 증가 6시간 동안 375,000RPS에서 500,000RPS로 분산하여 늘립니다.

가상 롤백 계획:

  • 95번째 백분위수 지연 시간이 500ms를 초과하거나 어느 단계에서든 오류 비율이 1시간 넘게 1%를 초과하는 경우 동적 구성을 사용하여 이전 단계로 즉시 롤백합니다.
  • 지연 시간과 오류 비율이 명목상의 수준으로 돌아올 때까지 이전 단계로 롤백을 계속합니다.

FCM에 문의해야 하는 경우

다음 중 하나라도 해당하는 경우 Firebase 지원팀을 통해 FCM에 문의하세요.

  • 기본 할당량이 더 이상 사용 사례를 충족하지 않습니다.
  • 3개월 이내에 전역적으로 100,000RPS 또는 대륙 내 30,000RPS 규모로 전송 패턴을 변경합니다.