在计算机科学中,幂等性是操作的一种属性,即多次应用操作与仅应用一次操作具有相同的最终效果。如果您向服务器发送了五次相同的请求,那么幂等系统可确保服务器上的结果在第一次成功尝试后不会发生变化。
除了确保结果相同之外,幂等操作的一个主要特征是,额外的调用不会产生副作用。这是构建弹性分布式系统的核心要求,因为间歇性网络服务中断或超时可能会导致客户端多次发送同一条消息。
类比:想想电梯上的“上行”按钮。按一下,电梯就会到达您所在的楼层。如果您在等待时又按了十次,结果还是一样,还是只有一部电梯到达您的楼层。多次按下按钮并不会召唤十部不同的电梯。相比之下,将商品添加到数字购物车通常不是幂等的。如果您点击“加入购物车”按钮五次,您的购物车中很可能最终会有五件相同的商品。
在超时或连接断开后安全地重试请求,而不必担心重复操作(例如对信用卡重复扣款)。
用户不需要复杂的状态跟踪,就能知道之前的请求是否成功;他们只需“重试直到成功”。
分布式系统可以通过重放日志或重新发送丢失的消息来从崩溃中恢复,而不会损坏数据。
REST 标准定义了不同类型的 Web 请求应如何运行。某些 HTTP 方法在设计上是“安全”或幂等的,这意味着规范期望它们即使重复执行也应表现出可预测的行为。而另一些方法则旨在创建新数据,需要格外注意以确保其在重试情况下的安全性。
根据 RFC 9110,一些标准方法本身是幂等的。重复执行这些操作,不应使服务器状态在初始请求的影响范围之外发生改变。
有些方法不是幂等的,因为它们的主要作用是以创建新内容或修改现有记录的一部分的方式更改数据。
在我们构建的系统中,幂等性通常是必需的。在某些情况下,系统会为我们处理此问题。在其他情况下,我们作为开发者需要采取行动才能实现这一目标。
最著名的例子是“重复扣款”问题。如果用户在支付机票费用时浏览器卡住,他们可能会再次点击“支付”。使用幂等性密钥的支付 API 可确保第二次点击识别为重试。这可以保护客户的银行账户,并降低处理重复交易退款的运营成本。
Terraform 和 Ansible 等工具依赖于幂等性。当您运行“创建 10GB 存储桶”脚本时,该工具会检查云的当前状态。
现代 Web API 通常会实现幂等性密钥标头(现在是标准化的 IETF 草案),以便开发者构建更强大的集成。
“upsert”(更新或插入)是一种经典的幂等数据库操作。与简单的“插入”操作不同,upsert 操作的含义是:“如果此记录存在,则更新它;如果不存在,则创建它。”