Bird 接受 SMS 之后、你的应用收到响应之前,连接可能会断开。用新的幂等键重试可能产生第二次发送,因为 Bird 会将其视为一个独立的请求。
幂等键如何工作?
为每次预期的 SMS 发送设置一个 Idempotency-Key 请求头,并在重试相同请求时复用它。只接受一次的保证意味着:三小时内匹配的重试必须对应同一次被接受的发送,即使你没有收到它的响应。
例如,一条订单确认消息在超时及重试过程中保持相同的幂等键。另一笔订单的确认消息则使用不同的幂等键。
重放的响应包含 Idempotency-Replay: true,你的日志可以据此区分重放与新处理的请求。
SMS 幂等键的作用域为你的工作区。Bird 按其幂等约定保留已完成的响应 三小时。超过该窗口后,同一幂等键可以执行新请求,因为其重放记录已过期。因此,一天后的重试需要先核实原始结果,再决定是否再次发送。
失败响应在告诉我什么?
错误码区分了三种情况:请求已变更、请求未完成和幂等保护不可用。
409且E01005 IdempotencyKeyReuse:同一幂等键被用于不同的请求。在重试之前先修正幂等键的分配,因为该幂等键属于原始请求。Bird 会比较方法、端点、路径与查询参数以及原始请求体。即使 JSON 中的空白字符变化也会使请求被视为不同。409且E01004 RequestInProgress:使用同一幂等键的并发请求尚未完成。短暂等待后使用相同的幂等键和请求重试,以便原始请求完成。503且E01033 IdempotencyUnavailable:执行前幂等保护不可用,因此本次尝试未执行。使用相同的幂等键和请求进行退避重试。此响应不能确定先前尝试的结果。- 其他
5xx响应或超时:使用相同的幂等键和请求进行退避重试。三小时内的这些重试受只接受一次的保证覆盖。重试次数用尽时停止重试。
幂等请求头在这些重试中保持请求的身份不变。
幂等键能保证不出现重复吗?
该保证是:在同一工作区内,三小时内使用相同幂等键的相同请求只会被接受一次。即使响应丢失,这些重试也必须对应一次被接受的发送。要确认是否送达,请查看消息状态。
超过三小时的保留窗口后,原来的幂等键可以标识一次新的操作。如果原始结果未知,请先核实,再重新提交。
保留你的应用事件和发送记录,以便在再次发送之前核实不确定的结果。在消息中包含订单号或参考编号,让收件人能够识别消息所对应的事件。
如果收件人手机上显示了两条相同的消息呢?
幂等键控制的是 API 的重试,而非收件人手机如何显示消息。仅凭截图无法确定重复消息的来源。
将完整的应用发送日志与 Bird 的消息记录进行比对。多个已接受的消息 ID 可以证明存在多次发送。在不完整的日志中只找到一个 ID 并不能证明重复发生在下游。联系支持团队排查时,请提供相关 ID、目标地址和时间戳。
我应该怎么做?
- 为每次预期的 SMS 发送 分配一个幂等键,并在重试时复用相同的请求。
- 对网络错误、超时和
5xx响应进行退避重试,在三小时内保持相同的幂等键和相同的请求。 - 修正请求变更冲突,并在原始请求仍在执行时延迟重试。
- 重试次数用尽或已过期的发送先保持未决状态,直到核实其结果,再决定是否需要再次发送。
简而言之
一个幂等键标识一次预期的发送。
在三小时内复用相同的幂等键和相同的请求。这些重试最终只会对应一次被接受的发送。
409可以识别已变更或未完成的请求。IdempotencyKeyReuse 表示请求已变更。RequestInProgress 表示原始请求仍在执行,需要延迟重试。
幂等保护不可用,本次尝试被阻止。
503 IdempotencyUnavailable 响应表示本次尝试未执行,但不能确定先前尝试的结果。
接受保护有保留窗口。
请在三小时内重试。超过该窗口后,先核实原始发送,再重新提交。