客户端等待超时,只说明本地在截止时间前没有收到完整响应。请求可能未离开客户端,也可能已经被对方处理,只是响应丢失。把超时一律当成失败并重试,容易造成重复扣款、重复创建或重复发送。可靠集成要将成功、明确未执行、结果未知建模为不同状态,并设计从未知状态收敛到确定结果的路径。🧭
一次调用经过DNS、连接建立、TLS、请求写入、对方排队、业务处理和响应读取。连接前失败可以说明请求大概率未送达;请求写入后发生读超时,则无法从客户端判断对方是否提交了副作用。中间网关返回错误也不等于源服务没有执行,因为错误可能发生在响应回程。要记录超时阶段、总耗时、请求关联ID、对方追踪号和尝试序号。
检查所有自动重试来源:SDK、HTTP代理、服务网格和业务代码可能各自重试。若每一层最多重试若干次,实际调用次数会相乘。将重试集中在一个有业务上下文的层,并明确总尝试数和截止时间。超时预算需留在上游请求总预算之内,同时给状态查询和本地提交留出时间。⏱️
每个逻辑操作生成稳定幂等键,同一操作的所有重试复用同一键。不同用户意图则必须有不同键,否则对方可能把合法的新操作误认为重复。需了解对方幂等机制的作用范围、键保留时间、并发请求处理方式以及相同键但不同参数时的行为。若对方保留时间短于本地补偿窗口,延迟重试可能重新执行副作用。
本地保存幂等键与业务操作、当前状态和请求摘要的关联。摘要可帮助发现同键不同载荷,不要将敏感请求体写入普通日志。状态可以包括待发送、处理中、结果未知、已确认成功、明确失败和人工核对;状态迁移需避免并发线程互相覆盖。🔐
退避采用逐步延长间隔并加入随机抖动,避免众多请求同步重试形成流量尖峰。设定每次操作的最大尝试次数、总时限和未知状态最大停留时间;超过停留时间应告警并指向责任队列。重点观察unknown_outcome_count、重试率、查询确认率、幂等冲突和未知状态年龄。📊
在测试环境模拟对方完成副作用后丢弃响应,系统应进入未知状态,复用原幂等键查询,并最终只确认一个业务结果。再模拟明确拒绝、连接前失败、查询服务暂不可用和同键参数冲突,检查每种情形的状态迁移。核对日志能以关联ID、幂等键摘要和尝试序号串联全过程,同时不包含凭据或完整敏感载荷。
验收指标不能只看调用成功率,还要核对最终业务结果唯一性、未知队列积压与最老年龄、重试放大比例和人工处理闭环。超时是本地观察事实;只有远端确认、可查询状态或经过幂等约束的收敛结果,才能作为操作完成证据。✅