API 请求超时就重试?用 Python 实现一个防重复提交机制
一、前言
在日常开发中,调用 API 是非常常见的操作。
但你有没有遇到过这样的情况:
调用接口提交数据,等待几秒后程序提示请求超时。于是我们重新发送请求,却发现系统中出现了两条相同的记录。
为什么请求超时了,服务端却可能已经执行成功?
原因在于,请求超时并不一定代表操作失败,也可能只是服务器的响应没有成功返回给客户端。
本文通过一个简单的 Python 示例,介绍如何利用幂等键(Idempotency Key)减少重复提交问题。
二、什么是 API 幂等性?
幂等性是指:对于同一个操作,重复执行多次,产生的预期业务效果与执行一次相同。
例如,用户点击一次「发布作品」按钮,服务端创建一条作品记录。
如果网络出现问题,客户端再次发送相同请求,服务端不应该因此创建第二条相同作品。
一个典型的异常流程如下:
客户端 服务端
| |
|------ 提交作品 ------>|
| | 创建成功
| X 响应丢失 |
| |
|------ 再次提交 ------>|
| | 可能重复创建
为了避免重复执行,可以给每次业务操作分配一个唯一的幂等键。
服务端记录该键对应的执行结果。当相同请求再次到来时,直接返回之前的结果,而不是重新执行创建操作。
三、Python 实战:模拟防重复提交
下面使用 Python 实现一个简化的作品发布服务。
不需要安装第三方库,Python 3.9 及以上版本即可运行。
完整代码
class GalleryService:
def __init__(self):
self.records = {}
self.created = 0
def publish(self, key, title):
# 已处理过的业务请求
if key in self.records:
saved_title, work_id = self.records[key]
if saved_title != title:
raise ValueError(
"相同幂等键不能对应不同作品"
)
return work_id, False
# 第一次处理请求
self.created += 1
work_id = f"work-{self.created:03d}"
self.records[key] = (title, work_id)
return work_id, True
service = GalleryService()
key = "publish-mini-rag-lab-001"
# 第一次提交:服务端成功,但模拟响应丢失
service.publish(key, "Mini RAG Lab")
print("第一次提交:服务端已创建作品,客户端响应丢失")
# 使用相同幂等键重试
work_id, is_new = service.publish(
key, "Mini RAG Lab"
)
print(f"原幂等键重试:{work_id},新建:{is_new}")
# 错误示范:重试时更换幂等键
other_id, other_new = service.publish(
"publish-mini-rag-lab-002",
"Mini RAG Lab"
)
print(f"错误地更换幂等键:{other_id},新建:{other_new}")
print(f"服务端创建总数:{service.created}")
四、运行结果分析
将代码保存为 idempotency_demo.py,运行:
python idempotency_demo.py
实际运行结果:
第一次提交:服务端已创建作品,客户端响应丢失
原幂等键重试:work-001,新建:False
错误地更换幂等键:work-002,新建:True
服务端创建总数:2
从结果中可以看到:
第一次请求成功创建了 work-001。
当我们使用相同的幂等键重试时,服务端直接返回之前的作品 ID,没有创建新记录。
但如果错误地使用新的幂等键,就会创建 work-002,造成重复提交。
这说明:重试同一次业务操作时,保持幂等键不变十分重要。
五、真实项目还需要考虑什么?
上面的示例只是一个便于理解的内存模拟。实际生产环境中,还需要注意:
1. 数据持久化
示例中的记录保存在 Python 字典里,程序重启后会丢失。实际系统通常需要数据库等持久化存储。
2. 并发安全
多个相同请求同时到达时,简单的查询再插入逻辑可能发生竞争。可以结合数据库唯一约束与事务保证只有一个请求成功创建记录。
3. 幂等键有效期
服务端通常需要设计幂等记录的保留时间,并明确超出有效期后的处理规则。
4. 请求内容校验
相同的幂等键不应该对应不同的业务请求,可以通过保存请求摘要来识别参数冲突。
另外,对于支付、订单和作品发布等重要操作,在网络超时后,还应优先查询服务端状态,而不是无条件重新发送请求。
六、总结
API 请求超时不等于操作失败。
在涉及数据创建、订单提交、任务执行等业务场景时,合理设计幂等机制可以有效降低重复操作的风险。
本文通过 Python 模拟了幂等键的基本工作方式,展示了重复请求如何复用已有结果。
可靠的系统不仅要保证请求能够执行,还要考虑请求被重复执行时会发生什么。
- 点赞
- 收藏
- 关注作者
评论(0)