后端教程中的陷阱
教程向你展示了一个简单的流程: 接收 Webhook。 更新数据库。 返回 200 OK。
你的代码在测试时运行良好。你将其推送到生产环境。然后,你发现数据库中出现了重复记录。用户被重复入账。数据条目不断堆积。
教程忽略了网络故障这一现实情况。
问题所在:不可靠的网络 网络会发生故障。你的服务器处理数据可能会变慢。DNS 错误可能会导致你的 200 OK 响应无法到达发送方。
当服务没有收到你的确认时,它会进行重试。它会再次发送同一个 Webhook。如果你的代码接受每一个请求,就会产生重复数据。
解决方案:幂等性 幂等性意味着多次执行相同的请求所产生的效果与执行单次请求的效果相同。
想想电梯按钮。按一次 5 楼的按钮会告诉电梯要去哪里。按十次也不会让电梯去 50 楼。结果保持不变。
你的 Webhook 必须像那个按钮一样工作。
如何修复 遵循以下步骤来构建安全的 Webhook:
- 获取事件的唯一 ID。
- 在执行任何操作之前,先在数据库中检查该 ID 是否存在。
- 如果 ID 已存在,则停止操作。返回 200 OK,以便发送方停止重试。
- 如果是新 ID,则处理数据。
- 立即将事件 ID 保存到你的数据库中。
Node.js 中的逻辑示例:
const eventId = req.body.event_id;
const existingEvent = await db.processedEvents.findUnique({
where: { id: eventId }
});
if (existingEvent) {
return res.status(200).send('Already processed');
}
await updateUserData(req.body.data);
await db.processedEvents.create({ data: { id: eventId } });
return res.status(200).send('Success');
为理想情况构建系统很容易。为应对故障构建系统才是真正的工程实践。
你是否遇到过因重试导致的重复数据?你是如何处理幂等性的?