같은 문자가 3번씩 갔다 — SMS 중복 발송 15번 고친 이야기

문제 해결 노트··12분 읽기·

같은 문자가 3번씩 갔다 — SMS 중복 발송 15번 고친 이야기

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층: 에러 종류별 분류
재시도 해도 안 되는 에러 재시도하면 될 수도 있는 에러
번호가 틀림 일시적 네트워크 장애
수신 거부됨 서버 일시 오류
잔액 부족 응답 타임아웃
번호가 틀린 건 100번 보내도 안 됩니다. 돈만 낭비. 재시도는 일시적 장애일 때만, 최대 2번까지만. 3층: 보내기 전 이력 확인 이미 "발송 완료" 상태인 건 무조건 스킵. "실패" 상태여도 에러 종류를 보고 재시도 여부 판단.

배운 것 — "중복 방지"는 한 레이어로 안 된다

이 경험에서 배운 건:

  • "중복 방지 추가해줘"만으로는 부족합니다. 중복이 발생하는 경로가 여러 개일 수 있어요. 메일 읽음 실패, 식별값 불안정, 동시 처리, 타임아웃 — 각각 다른 방어가 필요.
  • AI한테 "이미 시도한 것"을 알려주세요. 그래야 같은 제안을 반복하지 않고, 아직 안 다룬 원인을 짚어줍니다.
  • 근본 원인을 못 찾으면 끝나지 않습니다. 방어 레이어를 10개 쌓아도, 식별값이 불안정하면 계속 새어요. 근본을 고쳐야 나머지가 의미 있습니다.
  • 결국 10개 커밋, 15일에 걸쳐서 안정화됐어요. 지금은 중복 발송 0건으로 잘 돌아가고 있습니다.

    공유

    댓글