연락처 송금 큐에 시도별 처리 이력 추적 기능 추가
목차
큐는 돌아가는데 왜 실패했는지 모르겠음
연락처 송금 큐를 돌리고 있었는데, 배치가 한 번 돌면 큐 자체 상태(대기/처리/완료/실패)만 갱신되고 끝남. 실패가 났을 때 "언제, 어떤 단계에서, 어떤 사유로" 막혔는지 추적이 안 됐음. 파트너가 "내 송금 왜 안 갔냐"고 물어보면 로그 grep 떠서 시간대 맞춰보는 식이었는데, 같은 큐 아이템이 여러 번 재시도되면 어떤 시도가 어디서 실패한 건지 분리가 안 됨.
같은 큐 아이템이라도 시도(attempt) 단위로 이력을 남겨야 한다는 결론. 큐 테이블에 컬럼 추가하는 식으로는 한 줄짜리 최신 상태밖에 못 남기니까, 별도 처리 이력 테이블을 새로 깠음.
이력 테이블 설계
처리 이력은 큐와 1:N 관계. 한 큐 아이템에 대해 시도마다 row 한 줄.
| 컬럼 | 용도 |
|---|---|
| 큐 아이템 ID | 부모 큐 row 참조 |
| 시도 회차 | 1, 2, 3... 재시도 누적 |
| 단계 | 검증 / 결제대행사 호출 / 결과 폴링 / 통보 |
| 상태 | 성공 / 실패 / 타임아웃 |
| 사유 코드 | 잔액부족, 한도초과, 점검시간 등 |
| 외부 트랜잭션 ID | 결제대행사가 돌려준 키 |
| 처리 시각 | 단계 진입/완료 timestamp |
설계하면서 한 가지 정리한 것: 큐 자체의 상태는 "현재"만, 이력은 "지나온 길" 전체라는 역할 분리. 이거 안 해두면 운영 들어가서 컬럼 또 늘리고 또 늘림.
배치 쪽 손본 부분
배치는 큐를 한 건씩 잡아서 단계별로 돌리는데, 단계 진입/이탈마다 이력을 한 줄씩 박도록 끼워넣음. 의사코드로 대충 이런 흐름.
for item in 대기큐:
history.start(item, 단계="검증")
try:
validate(item)
history.success(item, 단계="검증")
except e:
history.fail(item, 단계="검증", 사유=e.code)
item.markFail(); continue
history.start(item, 단계="결제대행사 호출")
...
성공/실패 이력 박는 책임을 유틸로 한 곳에 모음. 단계마다 try-catch 안에서 이력 호출 분기를 만들면 코드가 너덜너덜해져서, 단계 컨텍스트 객체 넘기고 끝나는 시점에 한 번만 기록하도록 정리.
파트너 포털 화면
운영자용 어드민 화면이랑 파트너용 포털 화면을 나눠서 손봤음.
- 어드민: 큐 아이템 클릭 시 시도 회차별로 펼쳐서 단계/사유/외부 트랜잭션 ID 표시
- 파트너 포털: 시도 내역은 숨기고 최종 결과 + 사유 한 줄만 노출
- 양쪽 모두 검색 필터에 "사유 코드" 추가해서 같은 유형 실패 한 번에 모아서 봄
파트너에게 시도 회차까지 보여주면 "왜 3번이나 시도했냐"는 문의가 새로 생기니까 의도적으로 가렸음. 운영자에게는 다 보여주는 게 맞고.
회수한 것
- CS 문의 들어왔을 때 큐 아이템 ID 하나로 전체 흐름 재구성 가능
- 같은 사유 코드로 묶어서 보면 결제대행사 점검시간 패턴 같은 게 눈에 띔
- 배치 재시도 로직 디버깅할 때 "정말 N회 시도한 게 맞나" 검증이 됨
다음.
댓글 0
첫 댓글 달아줘.