요구사항에 같은 알림을 두 번 보내지 않는다고 적었습니다. 그런데 이것은 완벽히 달성할 수 없습니다. 그 이유와 대응이 이 절입니다.
넘기기와 기록 사이에 틈이 있다
제공자에게 넘긴 뒤 "보냈다" 를 기록해야 합니다. 그 사이에 우리 프로세스가 죽으면, 다시 살아난 뒤 그 알림을 아직 안 보낸 것으로 보고 다시 보냅니다.
순서를 바꿔도 문제가 남습니다. 먼저 기록하고 보내면 보내기가 실패했을 때 안 보낸 채로 끝납니다.
| 순서 | 실패하면 |
|---|---|
| 보내고 기록 | 두 번 보낼 수 있다 |
| 기록하고 보내기 | 안 보낼 수 있다 |
둘 중 하나를 골라야 합니다. 정확히 한 번은 없습니다.
채널마다 다르게 고른다
무엇이 더 나쁜지가 알림 종류와 채널에 따라 다릅니다.
| 알림 | 고르는 쪽 | 이유 |
|---|---|---|
| 인증 번호 | 두 번을 감수한다 | 못 받으면 로그인을 못 한다 |
| 마케팅 문자 | 안 보내는 쪽 | 두 번 보내면 돈이 두 배이고 짜증이 두 배 |
| 결제 완료 푸시 | 두 번을 감수한다 | 못 받으면 불안하다 |
이 판단을 알림 종류마다 적어 둡니다. 시스템 전체에 하나로 정하면 어느 쪽에서는 반드시 잘못된 선택이 됩니다.
중복을 줄이는 장치
완전히 없앨 수 없지만 크게 줄일 수 있습니다.
보내는 서비스가 알림마다 고유한 키를 붙인다
우리는 그 키를 기록하고, 이미 있으면 보내지 않는다
키를 우리가 만들면 안 됩니다. 서비스가 같은 요청을 두 번 보낸 경우를 구분할 수 없기 때문입니다. 키는 보내는 쪽이 그 알림을 식별하는 값이어야 합니다.
키가 없으면 우리가 만들 수는 있습니다. 받는 사람과 알림 종류와 시간 구간을 합치는 방식입니다. 완벽하지 않지만 같은 알림이 몇 초 안에 두 번 오는 흔한 경우를 잡습니다.
사용자 눈에 보이는 중복
기술적으로 한 번 보냈어도 사용자가 두 번 본 것처럼 느끼는 경우가 있습니다.
| 상황 | 사용자가 느끼는 것 |
|---|---|
| 같은 내용이 푸시와 메일로 | 두 번 받았다 |
| 비슷한 알림이 연달아 | 시끄럽다 |
| 이미 읽은 것에 대한 알림 | 왜 또 오나 |
중복 방지의 목적은 기록의 정확성이 아니라 사용자 경험입니다. 그래서 채널을 넘어선 판단이 필요합니다. 같은 알림을 여러 채널로 보내기로 했다면, 한 채널에서 확인되면 나머지를 취소하는 것이 좋습니다.
기록을 언제까지 두나
중복 판정을 위한 키 기록은 영구히 둘 필요가 없습니다. 중복은 대개 짧은 시간 안에 생깁니다.
며칠 정도 두고 지운다
그 기간이 곧 우리가 막을 수 있는 중복의 범위다
기간을 정하지 않으면 그 기록이 계속 자라고, 하루 5천만 건 규모에서는 곧 큰 저장소가 됩니다. 막을 범위를 정하는 것이 저장 비용을 정합니다.