1인 개발로 서핑 예보 앱을 운영하며 겪은 푸시 알림 중복 발송 사건과 해결 과정을 정리했습니다.
특정 조건이 충족될 때 사용자에게 알림을 보내는 흔한 기능인데, 서버를 재배포할 때마다
"이미 보낸 알림"이 다시 나가는 문제가 반복됐습니다.

■ 문제

  • 재배포/재시작 때마다 같은 알림이 중복 발송됨
  • 로컬에선 재현이 잘 안 되고, 배포 직후에만 터져서 원인 찾기가 까다로웠음

■ 원인

  • 중복 방지(dedup) 상태를 서버 메모리에만 들고 있었음
  • 재배포하면 프로세스가 새로 뜨면서 그 상태가 통째로 리셋 → "안 보낸 셈"이 되어 재발송

■ 해결

  • dedup 키를 부팅 시 DB에서 다시 채우는(seed-on-boot) 구조로 변경 → 재배포에도 상태 유지
  • '조건이 바뀌는 순간에만 알림' 방식이 그 사이 가중치 변화를 놓치는 문제도 발견
    → 사유를 누적해 단계적으로 올리는(에스컬레이션) 방식으로 전환
  • FCM 토큰은 1기기 1개 원칙으로 정리(토큰 갱신·중복 토큰 처리 포함)

■ 교훈

  • 알림 dedup처럼 "한 번만 일어나야 하는" 상태를 인메모리에만 두면 배포가 곧 버그가 됨
  • 상태의 생명주기를 프로세스가 아니라 영속 저장소 기준으로 설계해야 함
  • 트리거는 '전환 시점'보다 '현재 상태'를 기준으로 판단하는 편이 놓침이 적음

서버 푸시/알림, 크론·배치, 중복 방지 로직을 다루는 분들이 참고할 만한 실전 사례입니다.

댓글과 토론