同步与异步交互改变故障传播

比较请求响应与消息交互在时间耦合、反馈、顺序和恢复方面的差异。

同步与异步交互改变故障传播

同步和异步不是“快”与“慢”的简单区别。同步请求让调用方在当前交互中等待结果,便于立即反馈,却把下游延迟与可用性带入上游;异步消息把处理延后,降低时间上的同时在线要求,却增加交付、顺序、积压和状态解释。选择应从业务反馈和故障语义出发。

同步请求提供明确的当前结果

HTTP 请求响应是典型同步交互。调用方发送请求并等待状态码和表示,能够在同一用户动作中确认成功、拒绝或失败。查询、权限校验和需要即时确认的命令通常适合这种模式。

等待必须有期限。没有超时的调用可能长期占用线程、连接和内存;超时过短则会在正常尾部延迟下制造失败。调用方超时只表示它不再等待,不证明服务端没有完成操作,因此重试前还要考虑幂等与结果查询。

同步链路会累积延迟。A 等待 B,B 再等待 C 时,任何下游拥塞都会传到入口。连接池、线程池和队列也可能逐层耗尽,形成级联故障。断路、隔离、限流和降级用于限制传播,但会改变用户得到的结果。

异步消息分离提交与完成

异步交互中,生产者把消息写入可靠通道后即可继续,消费者稍后处理。接受消息通常只证明消息进入通道,不等于业务动作已经完成。界面和 API 必须区分“已接收”“处理中”“完成”和“失败”。

队列可以吸收短期流量峰值,使消费者按能力处理,但积压会增加结果延迟。若生产速率长期高于消费能力,队列只是延后故障。需要监测积压数量、最老消息年龄、处理失败和重试速率。

异步还支持一个事件被多个消费者独立使用,减少生产者对具体后续动作的知识。然而事件模式成为共享契约,字段语义、版本和隐私范围仍需治理。

交付保证不等于业务只执行一次

消息系统常提供至少一次、至多一次或其他交付语义。至少一次意味着消费者可能收到重复消息,需要用业务键、处理记录和幂等写入控制副作用。至多一次可能丢失消息,适合可容忍遗漏的遥测,不适合关键状态转换。

所谓恰好一次通常只在特定系统边界和条件内成立。消息确认成功但外部邮件已发送、数据库提交成功但确认丢失,都会产生难以原子化的副作用。工程设计应说明去重范围、保留时间和不可撤销操作的补偿方式。

生产者也可能在数据库事务提交后、消息发送前崩溃。事务发件箱等模式把待发送事件与业务状态写入同一事务,再由独立进程发布,降低状态和消息分离的窗口,但仍需处理重复发布。

顺序只在明确范围内成立

全局顺序代价高且常无必要。许多系统只需保证同一订单、用户或设备的事件按键有序。分区键决定相关消息是否进入同一顺序通道,也会影响热点和扩容。

消费者并行、重试和死信处理都可能改变完成顺序。后到事件若依赖前序状态,需要版本号、序列号或状态机拒绝过期更新。仅依赖消息时间戳不够,因为不同主机时钟、网络延迟和重放都会影响到达顺序。

事件时间与处理时间也不同。遥感处理任务可以晚到数小时,却仍属于原始获取时间。窗口计算和状态更新必须明确依据哪个时间。

错误反馈路径决定运维成本

同步失败可以直接返回调用者,调用者决定修正输入或重试。异步消费者发现永久性错误时,原请求上下文可能已经结束,需要把失败写入可查询状态、发送通知或进入人工处理队列。仅把消息移入死信队列而无人负责,并没有完成故障处理。

错误应区分临时依赖故障、格式不兼容、业务拒绝和无法识别状态。无限重试永久错误会阻塞队列并消耗资源;直接丢弃则会造成数据缺口。重试上限、退避、死信和恢复工具需要共同设计。

追踪异步链路还要传递关联 ID 和业务标识,记录生产、接收、处理与重试阶段。否则一次业务动作会在多个日志中失去联系。

一致性体验取决于读写路径

同步提交后立即从同一事实源读取,较容易提供读己之写。异步派生视图则可能暂时落后,用户刚完成动作却看不到结果。系统可以显示处理状态、读取主记录、使用版本令牌或在限定时间内提供会话一致性。

缓存和搜索索引通常异步更新,也属于这种延迟。产品文案不能把“已提交”显示成“已完成”,接口契约要说明何时可查询最终结果。延迟预算应与业务后果匹配,而不是笼统接受最终一致。

混合交互通常比单一模式更现实

一个发布动作可以同步校验权限和内容状态,在本地事务中确认发布,再异步生成静态页、搜索索引和通知。核心结果即时确定,耗时或可重试的派生工作在后台完成。边界取决于哪些结果必须一起成功。

反过来,把所有动作异步化会增加状态管理,把所有动作同步串联会扩大故障面。设计评审应列出调用者需要的反馈、可接受延迟、重复与丢失后果、顺序范围和恢复责任。

容量测试也要覆盖故障情形:消费者暂停时积压增长多快,恢复后是否压垮下游,同步依赖变慢时线程池是否耗尽。同步与异步选择最终决定时间耦合和故障传播,需要用系统级证据验证。

资料依据