知识卡片

同步调用的坏味道:登机牌案例说明故障应留在服务本地

普通读书笔记卡

内容

简单的同步服务调用(如BPMN服务任务里的REST调用)能隐藏大量复杂性,但正如分布式计算谬误所说,远程通信本质上不可靠——远程服务可能不可用、响应可能很慢,很容易就会需要服务支持长期运行模式来等待,但这一点经常被遗忘,成为架构里的坏味道。作者用亲身经历说明:值机时点击”取登机牌”触发了一次同步REST调用,收到”技术故障,请五分钟后重试”的提示——如果航空公司内部各环节(值机、条形码生成等)都是通过REST同步调用串起来的独立服务,故障处理的责任就被甩给了调用链最前端能处理状态的一方,在这个例子里就是发出请求的乘客本人:作者不得不靠自己的日历提醒才没忘记重试,最后拖到第二天才拿到登机牌。真正该问的是:为什么不是航空公司自己重试?他们明明知道客户联系方式,完全可以在登机牌准备好后异步发送——这样做不仅更方便,还能大幅减少需要关心这个故障的组件数量,降低系统整体复杂度。当一个服务能自己解决自己的故障时,它就把这个重要行为封装了起来,让所有客户端的日子都更好过、API也更简洁;把错误直接甩给客户端在某些场景下也可以是有意识做出的业务决策,但现实中更常见的情况是团队明明知道”该由自己处理状态”,却因为不想承担这种复杂性而选择放弃——为了让错误留在本地,值机服务应该做有状态的重试,而在服务内部引入工作流引擎正是处理这类状态和调度重试的解决方案之一。

参考来源

- 位置:《流程自动化实战:系统架构和软件开发视角》第9章《工作流引擎与集成挑战》"9.1.1 同步请求/响应"(源文件:_epub-src/EPUB/xhtml/Section0001_0013.xhtml) - 结论依据:原文用作者亲历的登机牌值机故障说明同步调用链把故障处理责任甩给最前端调用方的问题,并解释航空公司若自己异步重试能降低复杂度、让服务自行封装故障处理的价值,直接支撑本卡片结论。 - 原始内容:草图中设计的故障处理方式是由客户端负责的,在这个例子中,我不得不自己重试……当服务可以自己解决故障时,它就把重要的行为封装起来……更常见的情况是,团队明白这种故障解决需要处理状态,但他们不想引入这种复杂性。