什么是幂等性?

在计算机科学中,幂等性是操作的一种属性,即多次应用操作与仅应用一次操作具有相同的最终效果。如果您向服务器发送了五次相同的请求,那么幂等系统可确保服务器上的结果在第一次成功尝试后不会发生变化。

除了确保结果相同之外,幂等操作的一个主要特征是,额外的调用不会产生副作用。这是构建弹性分布式系统的核心要求,因为间歇性网络服务中断或超时可能会导致客户端多次发送同一条消息。

类比:想想电梯上的“上行”按钮。按一下,电梯就会到达您所在的楼层。如果您在等待时又按了十次,结果还是一样,还是只有一部电梯到达您的楼层。多次按下按钮并不会召唤十部不同的电梯。相比之下,将商品添加到数字购物车通常不是幂等的。如果您点击“加入购物车”按钮五次,您的购物车中很可能最终会有五件相同的商品。

幂等系统的主要优势

在超时或连接断开后安全地重试请求,而不必担心重复操作(例如对信用卡重复扣款)。

用户不需要复杂的状态跟踪,就能知道之前的请求是否成功;他们只需“重试直到成功”。

分布式系统可以通过重放日志或重新发送丢失的消息来从崩溃中恢复,而不会损坏数据。

幂等与非幂等 HTTP 方法

REST 标准定义了不同类型的 Web 请求应如何运行。某些 HTTP 方法在设计上是“安全”或幂等的,这意味着规范期望它们即使重复执行也应表现出可预测的行为。而另一些方法则旨在创建新数据,需要格外注意以确保其在重试情况下的安全性。

幂等方法(GET、PUT、DELETE)

根据 RFC 9110,一些标准方法本身是幂等的。重复执行这些操作,不应使服务器状态在初始请求的影响范围之外发生改变。

  • GET:此方法用于检索数据。由于它不会更改服务器上的任何内容,因此即使您调用它一百万次,资源也不会发生变化。
  • PUT:此方法会完全替换资源。如果您将用户的邮件更新为“user@example.com”三次,最终状态仍然是邮件为“user@example.com”。
  • DELETE:这将移除资源。如果您删除“订单 #123”,然后尝试再次删除,该订单仍会保持已删除状态。结果(订单消失)保持不变。

非幂等方法(POST、PATCH)

有些方法不是幂等的,因为它们的主要作用是以创建新内容或修改现有记录的一部分的方式更改数据。

  • POST:开发者使用 POST 创建新资源。如果没有幂等逻辑,两次发送相同的 POST 请求(例如“提交付款”)通常会导致两条单独的记录,并向客户收取两次费用。
  • PATCH:此方法用于应用部分更新。虽然可以使其幂等,但默认情况下通常不是幂等的,因为重复相对更改(例如“余额加 5”)每次调用都会导致不同的最终值。

如何实现幂等 API

  1. 生成唯一密钥:客户端创建一个唯一的字符串(如 UUID),并将其包含在自定义 HTTP 标头中。
  2. 拦截并验证:服务器检查 Memorystore 等高速数据存储区,查看该密钥是否最近已处理过。
  3. 处理状态:如果密钥是新的,则处理请求并保存结果。如果是重复请求,则立即返回存储的结果,而无需重新运行业务逻辑。

幂等性的常见应用场景

在我们构建的系统中,幂等性通常是必需的。在某些情况下,系统会为我们处理此问题。在其他情况下,我们作为开发者需要采取行动才能实现这一目标。

最著名的例子是“重复扣款”问题。如果用户在支付机票费用时浏览器卡住,他们可能会再次点击“支付”。使用幂等性密钥的支付 API 可确保第二次点击识别为重试。这可以保护客户的银行账户,并降低处理重复交易退款的运营成本。

  • 开发者需要采取行动:您必须在 API 请求中实现幂等性密钥(通常是 UUID),以确保第二次点击被识别为重试,从而保护客户的银行账户

Terraform 和 Ansible 等工具依赖于幂等性。当您运行“创建 10GB 存储桶”脚本时,该工具会检查云的当前状态。

  • 已为您处理:幂等性由 IaC 工具本身管理;作为开发者,您无需编写额外的逻辑来防止资源重复

现代 Web API 通常会实现幂等性密钥标头(现在是标准化的 IETF 草案),以便开发者构建更强大的集成。

  • 开发者需要采取行动:在构建后端时,您必须实现拦截这些密钥、检查之前尝试情况并返回缓存响应的逻辑

“upsert”(更新或插入)是一种经典的幂等数据库操作。与简单的“插入”操作不同,upsert 操作的含义是:“如果此记录存在,则更新它;如果不存在,则创建它。”

  • 已为您处理:此逻辑由数据库引擎原生处理,确保无论脚本运行多少次,记录都能收敛到正确状态

利用 Google Cloud 解决业务难题

新客户可获得 $300 赠金,用于抵扣 Google Cloud 的费用。
与 Google Cloud 销售专员联系,详细讨论您的独特挑战。

在 Google Cloud 上构建可靠的微服务

Google Cloud 提供了多种工具,可帮助开发者更轻松地实现这些模式。在托管式平台上构建应用,可以减少为确保数据安全而需要编写的“样板”代码量。

  • Cloud Run:当您使用 Cloud Run 处理来自 Pub/Sub 的事件时,请注意 Pub/Sub 默认可能会多次传送消息。在 Cloud Run 服务中编写幂等性代码是一项要求,以确保 AI 智能体或数据流水线不会重复处理同一事件。
  • 关于 Pub/Sub 的说明:虽然默认传送方式是基于推送的传送,但基于拉取的订阅支持仅传送一次。了解这两种类型有助于您为服务选择合适的复杂程度。

准备好构建了吗?

立即了解如何在 Cloud Run 上部署弹性、幂等服务。