LINE X-Line-Retry-Key:发送超时后如何安全重试
对于支持重试键的 LINE Messaging API 发送操作,应在第一次请求就带上 X-Line-Retry-Key,发生超时或可重试的服务端故障后,使用同一个 key、相同收件人和相同内容重试。每个新的逻辑请求生成一个十六进制 UUID。如果重试返回的 409 表示该 key 已被受理,应停止,而不是换一个 key 再发。这能在规定窗口内防止重复受理,但不保证用户实际收到消息。
要点
- Push、multicast、narrowcast 和 broadcast 支持重试键,不能推广到所有 LINE API。
- 在发送前持久化 key 和原始请求,而不是出错后才补建。
- LINE 规定 key 自首次请求起 24 小时有效。
- 请求受理、用户收到消息和入站 webhook 确认是三个不同结果。
X-Line-Retry-Key 保护的是什么
超时只说明应用没收到响应,不能证明 LINE 没有受理发送。每次尝试都换一个 UUID,会把不确定结果变成另一条独立请求。
LINE 的请求重试指南明确说明:带 key 的请求一旦被受理,后续使用同一个 key 的请求会作为重复请求被拒绝。第一次请求就必须带 key。原本不带 key 的请求超时后再补上,无法为之前的发送补回去重保护。
| 发送方式 | 官方文档中的重试键支持情况 |
|---|---|
| Push | 支持 |
| Multicast | 支持 |
| Narrowcast | 支持 |
| Broadcast | 支持 |
| 其他 API,包括 reply messages | 不在该支持清单中,不要统一添加此请求头 |
LINE 表示,在不支持的 API 上附加这个请求头会返回 400。这也不是 LINE MINI App 的通知令牌流程。若排查的是那套接口,请使用Service Message API 错误排查指南,不要直接套用本文。
在网络调用之前保存重试记录
以下是应用设计建议,不是新增的 LINE API 字段。
建立持久化发件记录,保存业务操作标识、渠道身份、发送方法、完整请求体、重试 UUID、首次尝试时间、重试截止时间和处理状态。按保留策略保护收件人资料与消息内容。访问令牌应从安全配置读取,不要混入任务记录或普通日志。
先保存记录,再发请求。重试时加载已经保存的 key 和请求,不要根据可能变化的订单或客户数据重新生成正文。LINE 明确要求复用 key 时,内容和收件人都不能改变。
为业务操作设置唯一标识,并用任务认领或锁控制 worker。否则两个 worker 可能为同一业务动作各建一个 UUID,两条请求都能被受理。重试键只识别带相同 key 的请求,并不知道两条独立任务其实是在做同一件事。
如果多个工具共用一个 Official Account,应先确定每种发送动作的归属。多工具接入检查清单解决共享渠道边界,而本地 outbox 负责单次发送任务的所有权。
根据实际结果决定下一步
遵循 LINE 的按状态码重试规则,不要把所有非成功响应都当成重发许可。
| 实际结果 | 建议的 worker 行为 |
|---|---|
2xx | 记录已受理,停止重试 |
| 超时或可重试的服务端故障 | 在预算内安排重试,保留原 key 和原请求 |
409,且表示 key 已被受理 | 记录此前已受理,保存 x-line-accepted-request-id 并停止 |
其他 4xx | 停止原样重试,检查请求或限制原因 |
| 窗口耗尽,仍无法确认是否受理 | 转入核对或人工处理,不要自动换 key |
重复受理响应中的 x-line-accepted-request-id 指向成功请求。它与每次请求自身的 x-line-request-id 不同。保留状态、时间和脱敏诊断信息,不要只按错误文本分支。
LINE 建议使用指数退避,并说明重试也计入 API 请求速率限制。调度器应设置自身的尝试次数预算,且不应安排超过 key 有效期的重试。24 小时从首次请求计算,不会因每次重试而重新开始。应用可以选择更保守的截止时间。
有效期结束后,未知结果仍然未知。新 key 代表一次新的发送决定,可能重复此前已经受理的消息。应先核对或明确审批,不能把更换 key 当成常规恢复动作。
已受理不等于已送达
LINE 明确提醒:重试键不保证消息可靠送达收件人。例如用户已屏蔽 Official Account,即使请求被受理,也不能由此断言消息送达。受理之后,不断重试同一 key 不是修复送达问题的手段。
应用状态应准确区分“LINE 已受理”和“客户已读”。同样,你的 webhook 接收器返回成功,只确认入站投递,并不确认出站回复已经发送。
UnifyPort 使用另一套契约
UnifyPort 的非官方接口连接消息账号,提供 message.received 等标准化事件。它不是同一 LINE Official Account Messaging API 渠道里的另一个发送工具,公开发送文档也没有说明支持 X-Line-Retry-Key。
为 UnifyPort 实现发送重试前,先查看文本消息接口。不要把 LINE 的 24 小时有效期或重复受理响应直接移植过去。请求追踪标识也不自动等于幂等保证。
接收入站事件时,配置 signing_secret,按 X-Device-Timestamp、一个点和原始请求体计算 HMAC-SHA256,验证 X-Device-Signature。确认与重试行为以webhook 投递文档为准。入站事件去重和出站发送去重解决不同问题,完成一个不代表另一个也已实现。
需要 Official Account 原生发送功能时,应使用官方 Messaging API。切换到普通账号接口,不能修复此前通过官方 API 发出、结果不明的请求。
常见问题
第一次超时之后才创建 key 可以吗?
不能用它保护之前的请求。支持此功能的 API 必须从首次尝试起就携带 key。
收到 409,是否应该换 UUID 重发?
如果它表示同一个 key 已被受理,就不应该。保存成功请求标识,结束该操作的重试。
保留 key,但更换收件人可以吗?
不可以。LINE 要求重试内容与收件人都保持不变。业务动作有变化时,应另行判断,而不是修改原重试任务。
所有 LINE 消息 API 都适用吗?
不适用。只用于官方列出的支持方法,不能直接套到 MINI App service messages 或 UnifyPort 发送接口。
下一步与参考资料
检查一个出站 worker:进程崩溃后,能否恢复同一个 key 和同一份请求?先用本地模拟服务测试这一边界,再进行受控的真实发送测试。如果使用的是消息账号接入路径,请查看 UnifyPort 发送文档。
官方资料核对日期:2026-09-28。
让消息接入变成一条稳定的产品管线。
先用统一 API 跑通发送,再用标准事件把所有入站消息接回业务系统。