멱등성 — 두 번 눌러도 한 번만 결제되게 · 재시도와 중복 · 实验
두 번 눌러도 한 번만
目标
在网络中,重试不可避免。 当客户端没有收到响应时,
它无法区分请求根本没有到达,还是请求已到达、只有响应没能返回。
因此,重复请求必须由服务器阻止。 本实验会逐步修复一个特意设计为
非幂等的支付 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。如果只用 & 启动,切换 Shell 时服务器也会一起终止。
需要修改的位置
只修改 server.py 中的 handle_pay 一个函数。idem 表已经创建好,
其中包含键、请求哈希、状态、响应和时间。
重新启动服务器时
ps -eo pid,args | awk '$2 ~ /python3$/ && $3 == "server.py" {print $1}' | xargs -r kill不要使用 pkill -f server.py。该模式还会匹配**执行这条命令的 Shell
命令行**,从而杀死它自己。
步骤
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个步骤
- 重试会造成重复支付
- 相同键返回相同答案
- 没有键时拒绝请求
- 相同键对应不同正文时
- 相同键同时到达时
- 进程重启后还能否记住
- 哪些错误应该重试
- 总结三个要点