파트너 입금 정산 자동화로 야간 누락 제로 달성
목차
왜 자동화했나
파트너 입금 확인을 매번 손으로 처리하다 보니 누락이 생김. 메신저로 알림 와서 → 사람이 브라우저 열고 → 링크 타고 들어가서 → 내용 확인 → 다시 내부 시스템에 등록하는 패턴이 반복됐는데, 야간엔 처리가 늦어져서 정산이 밀림. "이거 왜 사람이 함?" 싶어서 파이프라인으로 묶음.
처리 흐름
| 단계 | 주체 | 역할 |
|---|---|---|
| 1 | 메신저 | 입금 알림 수신 |
| 2 | 브라우저 확장 | 알림 본문에서 URL 캡처 |
| 3 | 워커 | 큐에서 꺼내 내부 API로 전달 |
| 4 | 수신 서비스 | 파싱 후 입금건 매칭 |
수신부 의사코드 정도만 옮기면 이런 모양:
fun onReceive(payload):
url = extractUrl(payload.text)
if url == null: return
queue.enqueue(Job(url, payload.timestamp, hash(payload.text)))
브라우저 → 서버 구간은 굳이 동기로 묶지 않고 큐를 한 번 끼워서 끊었음. 메신저 쪽이 막혀도 서버는 살아있게.
삽질 포인트
- 메신저 본문에 줄바꿈이 들어가서 정규식이 두 번 깨짐. 멀티라인 매칭으로 바꾸고 끝
- URL이 단축링크라 한 번 더 리다이렉트 따라가야 했음. HEAD 요청 후 location 헤더 추출
- 워커가 동일 메시지를 두 번 처리하는 케이스. 본문 해시를 키로 in-memory dedupe 추가
- 빌드 스크립트에서 HTTP 클라이언트 버전이 다른 모듈과 충돌. 의존성 트리 정리해서 단일 버전으로 강제
회고
처음엔 cron 한 줄이면 끝날 줄 알았는데, 메신저 → 브라우저 → 서버 세 경계를 넘어야 해서 실패 지점이 단계마다 다름. 큐 끼워서 분리하길 잘했음. 동기 호출로 짰으면 메신저 푸시 한 번 막힐 때 전체가 같이 죽었을 것.
배운 것 정리하면
- 외부 입력은 무조건 멀티라인 가정. 한 줄이라고 믿으면 운영에서 바로 깨짐
- dedupe 키는 본문 해시. timestamp는 재전송 케이스에서 못 막음
- 세 시스템 이상 엮이면 큐. 직결로 묶지 말 것
야간 누락이 0건으로 내려갔고, 운영팀이 다른 작업에 시간 쓸 수 있게 됐음. 실패 케이스를 별도 알림 채널로 빼는 게 다음 작업.
다음
댓글 0
첫 댓글 달아줘.