통합과 배포 · 재시도가 만드는 중복 · 실습
응답을 잃어버리는 결제 API 상대하기
목표
타임아웃 뒤의 재시도가 어떻게 중복 결제를 만드는지 직접 만들어 보고,
멱등키로 막습니다. 그리고 키를 붙였는데도 안 되는 경우까지 확인합니다.
환경
/opt/app/pay.py 는 고객사 결제 API 를 흉내 낸 것입니다. 고칠 대상이
아니라 상대편입니다.
mkdir -p /root/idemnohup python3 /opt/app/pay.py > /tmp/pay.log 2>&1 &sleep 1curl -s http://127.0.0.1:8021/healthPOST /payments 결제 하나를 기록한다 Idempotency-Key 헤더가 있고 이미 본 키면 새로 기록하지 않고 저장해 둔 결과를 그대로 돌려준다GET /payments 지금까지 기록된 결제 전부POST /reset 상태 초기화짝수 번째 요청은 처리를 끝내고 응답만 6초 늦춥니다. 2초로 타임아웃을
걸면 클라이언트는 실패로 보지만 서버에는 이미 기록돼 있습니다. 이것이
"불확실한 결과" 입니다.
만들 것
전부 /root/idem/ 아래입니다.
naive.sh 멱등키 없이. 타임아웃이면 다시 보낸다naive.txt 그 결과와 왜 그런지safe.sh 비즈니스 행위 하나에 키 하나. 재시도에도 같은 키newkey.sh 시도마다 새 키를 만든다 (일부러 틀린 형태)newkey.txt 그 결과와 키를 무엇 단위로 만들어야 하는지backoff.sh 대기 시간 간격을 낸다retryable.sh 상태를 받아 재시도 여부를 답한다payments.csv 조사할 결제 기록forensics.txt 중복을 찾고 원인을 지목한 결과report.md 정리채점 방식
채점기가 매번 서버를 초기화하고 여러분의 스크립트를 직접 돌린 뒤
기록을 셉니다. 적어 놓은 숫자가 아니라 실제로 남은 기록을 봅니다.
naive.sh 기록 > 주문 이어야 한다 (중복이 생겨야 한다)safe.sh 기록 = 주문 이어야 한다 (정확히 한 번)newkey.sh 기록 > 주문 이어야 한다 (키가 무력해진다)backoff.sh 간격이 늘고, 두 번 돌리면 달라야 한다단계
1. 결제 API 를 띄웁니다.
2. naive.sh — 멱등키 없이 주문 4건 이상을 결제하고, 타임아웃이면
다시 보냅니다. 결과를 naive.txt 에 적습니다.
3. safe.sh — 주문마다 키 하나를 정하고, 재시도할 때 같은 키를 다시 씁니다.
4. newkey.sh — 키를 붙이되 시도마다 새로 만듭니다. newkey.txt 에
왜 소용없는지 적습니다.
5. backoff.sh — 재시도 간격을 4개 이상 냅니다. 지수적으로 늘고,
무작위가 섞여 있어야 합니다.
6. retryable.sh — 상태(500, 429, 400, timeout 등)를 인자로 받아yes 또는 no 를 냅니다.
7. payments.csv 를 만들고 중복을 찾습니다. 중복 건들의 시각 간격이
원인을 말해 줍니다.
8. 정리합니다.
참고
7단계의 재료는 이렇게 만듭니다.
cat > /root/idem/payments.csv <<'CSV'payment_id,order_id,created_atPAY-1,ORD-1,2026-09-07T10:00:00ZPAY-2,ORD-2,2026-09-07T10:00:05ZPAY-3,ORD-2,2026-09-07T10:00:06ZPAY-4,ORD-2,2026-09-07T10:00:08ZPAY-5,ORD-2,2026-09-07T10:00:12ZPAY-6,ORD-3,2026-09-07T10:01:00ZPAY-7,ORD-4,2026-09-07T10:02:00ZPAY-8,ORD-4,2026-09-07T10:02:01ZPAY-9,ORD-4,2026-09-07T10:02:03ZPAY-10,ORD-4,2026-09-07T10:02:07ZCSV간격이 1초 · 2초 · 4초로 배가 되는 것이 보이면 거의 확정입니다.
단계 8개
- 응답을 잃어버리는 API 띄우기
- 타임아웃을 실패로 보면
- 멱등키로 정확히 한 번
- 키를 붙였는데도 안 되는 경우
- 간격을 늘리고 흩뜨린다
- 무엇을 재시도하고 무엇을 안 하나
- 간격이 원인을 말해 준다
- 정리