SMS

如何避免重复发送同一条 SMS?

对同一 SMS 请求的重试复用同一个 Idempotency-Key,这样 Bird 就能重放已保留的响应而不会再次发送。

Bird 接受 SMS 之后、你的应用收到响应之前,连接可能会断开。用新的幂等键重试可能产生第二次发送,因为 Bird 会将其视为一个独立的请求。

幂等键如何工作?

你为每次预期的 SMS 发送设置一个 Idempotency-Key 请求头,并在重试相同请求时复用它。当 Bird 保留了原始响应后,匹配的重试会返回该响应而不会再次执行发送。

例如,一条订单确认消息在超时及重试过程中保持相同的幂等键。另一笔订单的确认消息则使用不同的幂等键。

重放的响应包含 Idempotency-Replay: true,你的日志可以据此区分重放与新处理的请求。

SMS 幂等键的作用域为你的工作区。Bird 按其幂等约定保留已完成的响应 三小时。超过该窗口后,同一幂等键可以执行新请求,因为其重放记录已过期。因此,一天后的重试需要先核实原始结果,再决定是否再次发送。

失败响应在告诉我什么?

错误码区分了三种情况:请求已变更、请求未完成和幂等保护不可用。

  • 409 且 E01005 IdempotencyKeyReuse:同一幂等键被用于不同的请求。在重试之前先修正幂等键的分配,因为该幂等键属于原始请求。Bird 会比较方法、端点、路径与查询参数以及原始请求体。即使 JSON 中的空白字符变化也会使请求被视为不同。
  • 409 且 E01004 RequestInProgress:使用同一幂等键的并发请求尚未完成。短暂等待后使用相同的幂等键和请求重试,以便原始请求完成。进行中的锁会在 30 秒内过期。过期并不能确定原始发送是否已生效。
  • 503 且 E01033 IdempotencyUnavailable:执行前幂等保护不可用,因此本次尝试未执行。使用相同的幂等键和请求进行退避重试。此响应不能确定先前尝试的结果。
  • 其他 5xx 响应或超时:使用相同的幂等键和请求进行退避重试。Bird 不会保留 5xx 响应。重试会重放已保留的成功响应,如果没有保留任何响应,则可能再次执行。

幂等请求头在这些重试中保持请求的身份不变。

幂等键能保证不出现重复吗?

幂等键能减少重复发送,但不能保证只执行一次。

发送可能在 Bird 保留响应之前就已生效。如果响应保留失败或进行中的锁过期,重试可能会再次执行发送。三小时的保留窗口同样限制了重放保护的范围。

保留你的应用事件和发送记录,以便在再次发送之前核实不确定的结果。在消息中包含订单号或参考编号,让收件人能够识别消息所对应的事件。

如果收件人手机上显示了两条相同的消息呢?

幂等键控制的是 API 的重试,而非收件人手机如何显示消息。仅凭截图无法确定重复消息的来源。

将完整的应用发送日志与 Bird 的消息记录进行比对。多个已接受的消息 ID 可以证明存在多次发送。在不完整的日志中只找到一个 ID 并不能证明重复发生在下游。联系支持团队排查时,请提供相关 ID、目标地址和时间戳。

我应该怎么做?

  1. 为每次预期的 SMS 发送 分配一个幂等键,并在重试时复用相同的请求。
  2. 对网络错误、超时和 5xx 响应进行退避重试,保留幂等键以利用可用的重放保护。
  3. 修正请求变更冲突,并在原始请求仍在执行时延迟重试。
  4. 核实不确定的发送,包括超出三小时重放窗口的发送,然后再决定是否再次发送。

简而言之

  1. 一个幂等键标识一次预期的发送。

    重试时复用相同的幂等键和请求。已保留的响应在三小时内可被重放。

  2. 409 可以识别已变更或未完成的请求。

    IdempotencyKeyReuse 表示请求已变更。RequestInProgress 表示原始请求仍在执行,需要延迟重试。

  3. 幂等保护不可用,本次尝试被阻止。

    503 IdempotencyUnavailable 响应表示本次尝试未执行,但不能确定先前尝试的结果。

  4. 响应重放降低了重复发送风险,但不能完全消除。

    发送可能在响应被保留之前就已生效。过期的重放记录也会允许新的执行。

基于同一网络构建。

测试 API 密钥即刻获取。添加付款方式并验证发送者身份后,即可解锁生产环境。

你的下一个创意。
随时连接。