每项服务都是中央消息总线的生产者和消费者。编排器的职责是将消息路由到他们相应的服务。每个组件消费一个传入事件或消息,并在消息队列上生成响应。编排器消耗此响应并进行转换,然后再前进到下一步。该循环继续,直到指定的工作流程达到系统中的最后一个状态。
在这种风格下,工作流管理对于编排器来说是本地的。这种系统在处理写入流量很大时有很好的表现,同步消费者需要调解。这在所有异步通信变体中都很流行。
在编排系统中,协同耦合问题的解决方案更加优雅。在这种情况下,工作流工作在编排器上,丰富的工作流规范可以捕获通知类型和内容模板等信息,对工作流程的任何更改都保留在编排器服务中。
编排和事件协同混合使用
另一个成功的变体是具有编排和事件协同的混合系统。编排非常适合显示的工作流执行,而协同可以处理隐式执行。在工作流程中执行叶节点可能是隐含的,工作流规范可以促进在特定步骤中发生事件,这可能会导致执行任务,如通知,索引等等,编排可以继续推动显式执行。
这两种方法的融合提供了近乎完美的方案,虽然仍需要采取预防措施以确保它们不会责任重叠,并且明确边界以决定它们的功能。
概述异步风格的体系结构解决了同步体系结构系统所具有的一些缺陷。异步结构在处理突发大量请求时表现更好。中央队列允许服务赶上合理的请求积压,当很多请求在短时间内出现或者服务暂时关闭时,这是非常有用的。
每个服务都以消费者或生产者的身份连接到消息队列,只有消息队列需要服务发现。因此,对中央服务发现解决方案的需求不那么紧迫。此外,由于服务的多个实例连接到队列,因此不需要外部负载平衡,这可以防止负载平衡器引入导致的隔离级别提升。它还使服务能够无缝线扩展。
权衡本质上是异步的服务流可能很难通过系统进行跟踪。采用异步通信的系统会有一些折衷,我们来看看其中的一些权衡点。
更高的系统复杂性
异步系统往往比同步系统复杂得多。然而,系统的复杂性和性能以及规模的要求是合理的开销。一旦采用协调器和单个组件,就需要接受异步执行。
读取/查询需要中介
除非专门处理,否则同步消费者受异步体系结构的影响最大。要么消费者适应异步系统的工作,要么系统为消费者提供同步接口。
异步架构非常适合写入繁重的系统。但是,它需要协调读取/查询同步,有几种方法来管理这种需求,每种都有一定的复杂性。
同步包装
所有方法中最简单的是在异步系统上构建同步包装。这是一个可以调用下游异步流程的入口点。同时,它保存等待的请求,直到响应返回或发生超时。同步包装是一个有状态的组件。传入的请求将自己绑定到它所在的服务器上。来自下游服务的响应需要到达原始请求正在等待的服务器。这对分布式系统来说并不理想,尤其是那种大规模运行的系统。但是,编写起来很简单,而且易于管理。这种方法符合具有合理的缩放和性能需求的系统的需求。在进行更为剧烈的重构之前,可以考虑同步封装。
CQRS
CQRS是一种将读取与写入分离的架构风格。CQRS给系统带来了大量的风险和复杂性,它非常适合大规模运行并需要大量读取和写入的系统。在CQRS体系结构中,数据从写数据库流向读数据库,查询在读取优化的数据库上运行,读/写层是分开的,系统保持最终一致性。两个层的优化是独立的。这样的系统结构更复杂,但可以具有更大的规模。而且,组件可以保持无状态(与同步包装不同)。
双重支持