1인 개발로 서핑 예보 앱을 운영하며 겪은 푸시 알림 중복 발송 사건과 해결 과정을 정리했습니다.
특정 조건이 충족될 때 사용자에게 알림을 보내는 흔한 기능인데, 서버를 재배포할 때마다
"이미 보낸 알림"이 다시 나가는 문제가 반복됐습니다.
■ 문제
- 재배포/재시작 때마다 같은 알림이 중복 발송됨
- 로컬에선 재현이 잘 안 되고, 배포 직후에만 터져서 원인 찾기가 까다로웠음
■ 원인
- 중복 방지(dedup) 상태를 서버 메모리에만 들고 있었음
- 재배포하면 프로세스가 새로 뜨면서 그 상태가 통째로 리셋 → "안 보낸 셈"이 되어 재발송
■ 해결
- dedup 키를 부팅 시 DB에서 다시 채우는(seed-on-boot) 구조로 변경 → 재배포에도 상태 유지
- '조건이 바뀌는 순간에만 알림' 방식이 그 사이 가중치 변화를 놓치는 문제도 발견
→ 사유를 누적해 단계적으로 올리는(에스컬레이션) 방식으로 전환 - FCM 토큰은 1기기 1개 원칙으로 정리(토큰 갱신·중복 토큰 처리 포함)
■ 교훈
- 알림 dedup처럼 "한 번만 일어나야 하는" 상태를 인메모리에만 두면 배포가 곧 버그가 됨
- 상태의 생명주기를 프로세스가 아니라 영속 저장소 기준으로 설계해야 함
- 트리거는 '전환 시점'보다 '현재 상태'를 기준으로 판단하는 편이 놓침이 적음
서버 푸시/알림, 크론·배치, 중복 방지 로직을 다루는 분들이 참고할 만한 실전 사례입니다.