멱등성 — 두 번 눌러도 한 번만 결제되게 · 재시도와 중복 · 실습
두 번 눌러도 한 번만
목표
네트워크에서 재시도는 피할 수 없습니다. 클라이언트가 응답을 못 받았을 때,
요청이 도착 안 한 건지 도착했는데 응답만 못 온 건지 구별할 방법이 없기
때문입니다.
그러니 중복은 서버가 막아야 합니다. 이 실습은 일부러 멱등하지 않게 만든
결제 API 를 고쳐 나갑니다.
시작
cp /opt/lab/idem/* . && chmod +x *.shsetsid nohup python3 server.py > s.log 2>&1 </dev/null &./probe.sh k1 # 키 k1 로 결제./ledger.sh # 지금까지 적립된 것setsid nohup 을 붙이세요. 그냥 & 로 띄우면 셸이 바뀔 때 같이 죽습니다.
고칠 곳
server.py 의 handle_pay 하나입니다. idem 테이블은 이미 만들어져
있습니다 — 키·요청해시·상태·응답·시각.
서버를 다시 띄울 때
ps -eo pid,args | awk '$2 ~ /python3$/ && $3 == "server.py" {print $1}' | xargs -r killpkill -f server.py 를 쓰지 마세요. 그 패턴은 **이 명령을 실행한 셸의
명령줄에도 걸려서** 자기 자신을 죽입니다.
단계
1. 중복 재현 → 01-duplicate.txt
2. 같은 키면 같은 답 → 채점기가 직접 확인
3. 키 없으면 거절 → 03-nokey.txt
4. 같은 키 다른 본문 → 04-conflict.txt
5. 동시 요청 → 05-race.txt
6. 재시작해도 기억 → 06-persist.txt
7. 재시도 정책 → 07-retry.md
8. 정리 → 08-notes.md
참고
2·5·6단계는 채점기가 직접 서버를 띄워 요청을 보냅니다. 로그를 베껴
오는 것으로는 통과하지 못합니다.
단계 8개
- 재시도가 중복 결제를 만든다
- 같은 키면 같은 답을 돌려준다
- 키가 없으면 거절한다
- 같은 키에 다른 본문이 오면
- 동시에 같은 키가 오면
- 프로세스를 껐다 켜도 기억하나
- 어떤 오류에 재시도해야 하나
- 세 가지를 정리한다