같은 문자가 3번씩 갔다 — SMS 중복 발송 15번 고친 이야기
같은 문자가 3번씩 갔다 — SMS 중복 발송 15번 고친 이야기
거래처에서 전화가 왔다 — "같은 문자가 세 번씩 와요"
Echo Mail을 실제 업무에 쓴 지 2주째. 발주 메일이 오면 담당자한테 자동으로 문자를 보내주는 시스템인데, 거래처에서 전화가 왔어요.
"같은 내용의 문자가 하루에 두세 번씩 오는데요?"
DB를 열어봤더니 진짜였습니다. 하나의 메일에 대해 문자가 2~3건씩 나가고 있었어요. 비용 낭비도 문제지만, 거래처한테 스팸 취급 받는 게 더 큰 문제였습니다.
"중복 방지 추가해줘" — 이 한 마디의 한계
처음에 AI한테 이렇게 시켰어요:
SMS가 중복으로 발송돼요. 중복 방지 기능 추가해줘.
AI가 "발송 이력 테이블을 만들어서 보내기 전에 확인하면 됩니다"라고 했어요. 맞는 말이에요. 이력 테이블을 만들고 "이미 보냈으면 스킵" 로직을 넣었습니다.
이틀 뒤에 또 중복이 터졌습니다.
왜? 같은 메일이 DB에 두 번 저장되면서, 각각 다른 ID를 받은 거예요. 이력 테이블에서 ID로 "이미 보냈나?" 확인해봤자, 서로 다른 ID니까 "새 건"으로 판단한 겁니다.
비유하면: 같은 택배가 두 개 왔는데, 송장번호가 달라서 "다른 택배"로 처리한 상황.
프롬프트를 바꾸니까 진짜 원인이 나왔다
당신은 메시징 시스템 전문가입니다.
[환경] 메일 수신 → DB 저장 → 문자 발송
[증상] 같은 메일에 대해 문자가 2~3회 발송됨
[이미 시도한 것] 발송 이력 테이블로 체크
→ 같은 메일이 DB에 중복 저장되면서 각각 다른 ID로 발송됨
[의심 포인트] 메일을 읽은 후 '읽음 처리'가 안 되는 것 같음
전체 흐름에서 중복이 발생할 수 있는 모든 지점을 분석해주세요.
"이미 시도한 것"을 넣으니까 AI가 이력 테이블을 또 제안하지 않고, 진짜 원인을 짚어줬어요.
메일함에서 메일을 가져온 뒤 "읽음" 표시를 하는데, 이게 실패하면 다음에 같은 메일을 새 메일로 또 가져오는 거였습니다.
고치면 다른 데서 터지는 5연쇄
여기서부터 지옥이었어요. 원인이 하나가 아니라 5개였습니다:
| # | 뭐가 문제였나 | 비유 |
|---|---|---|
| 1 | 메일 읽음 처리 실패 → 같은 메일 재처리 | 택배 수령 확인을 안 해서 같은 택배 재배달 |
| 2 | 메일 본문으로 만든 식별값이 매번 달라짐 | 같은 택배인데 올 때마다 송장번호가 바뀜 |
| 3 | 프로그램 두 개가 동시에 같은 메일 처리 | 직원 두 명이 같은 주문 동시에 처리 |
| 4 | 문자는 보냈는데 응답이 늦어서 "실패"로 기록 → 재발송 | 택배 도착했는데 배송 완료 버튼 안 눌림 → 재배송 |
| 5 | 잘못된 번호에도 재시도 | 없는 주소에 택배 3번 보내기 |
삽질의 하이라이트 — 11월 26일
이 날 하루에만 관련 수정을 4개 했습니다. 고치고 테스트하고, 다른 케이스에서 터지고, 또 고치는 반복.
AI한테 계속 피드백을 줬는데, 핵심은 "이미 시도한 방어를 전부 알려주는 것"이었어요:
중복 방지를 5번 수정했는데 여전히 엣지 케이스가 있습니다.
현재까지 적용한 방어:
1. 발송 이력 체크
2. 메일 읽음 처리 수정
3. 메일 고유번호 기반 중복 확인
4. 보낸사람+제목+날짜 조합 체크
그런데 문자 서비스에서 실제로 발송은 됐는데
응답이 늦어서 "실패"로 기록되면 재발송되는 케이스가 있습니다.
같은 업체+담당자+오늘 날짜 기준으로
추가 중복 체크를 만들어주세요.
이미 시도한 4가지를 다 알려주니까, AI가 같은 제안을 반복하지 않고 타임아웃 시나리오에 맞는 해결책을 줬어요.
근본 원인 — 메일 식별값이 불안정했다
5개 원인 중 가장 근본적인 건 2번이었어요. 메일에는 고유번호(Message-ID)가 있는데, 이게 없는 메일이 있어요. 그런 메일은 본문 내용으로 대체 식별값을 만들었는데, 메일 본문을 가져올 때마다 미세하게 달라지는 거였습니다.
같은 메일인데 식별값이 다르면 → DB에 별개로 저장 → 각각 문자 발송 → 중복.
해결: 본문 기반 식별값 대신, 메일 서버가 부여하는 고유번호(UID)를 쓰도록 변경. UID는 같은 메일함에서 절대 안 바뀌니까요.
[전] 식별값 = 보낸사람 + 제목 + 날짜 + 본문해시 ← 본문해시가 불안정!
[후] 식별값 = 보낸사람 + 날짜 + UID ← UID는 고정값
이 한 줄 변경이 중복의 근본 원인을 해결했습니다.
최종 방어 — 3중 체크
10개 커밋 끝에 쌓은 방어 레이어:
1층: DB에서 차단 같은 메일 + 같은 담당자 조합이면 DB 자체에서 저장 거부. 코드가 실수해도 DB가 막아줌. 2층: 에러 종류별 분류| 재시도 해도 안 되는 에러 | 재시도하면 될 수도 있는 에러 |
|---|---|
| 번호가 틀림 | 일시적 네트워크 장애 |
| 수신 거부됨 | 서버 일시 오류 |
| 잔액 부족 | 응답 타임아웃 |
배운 것 — "중복 방지"는 한 레이어로 안 된다
이 경험에서 배운 건:
결국 10개 커밋, 15일에 걸쳐서 안정화됐어요. 지금은 중복 발송 0건으로 잘 돌아가고 있습니다.