LabHub
学习 学习路径 课程

멱등성 — 두 번 눌러도 한 번만 결제되게 · 재시도와 중복 · 实验

두 번 눌러도 한 번만

在 LabHub 中继续学习

目标

在网络中,重试不可避免。 当客户端没有收到响应时,
无法区分请求根本没有到达,还是请求已到达、只有响应没能返回。

因此,重复请求必须由服务器阻止。 本实验会逐步修复一个特意设计为
非幂等的支付 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个步骤

  1. 重试会造成重复支付
  2. 相同键返回相同答案
  3. 没有键时拒绝请求
  4. 相同键对应不同正文时
  5. 相同键同时到达时
  6. 进程重启后还能否记住
  7. 哪些错误应该重试
  8. 总结三个要点