微服务可能会在其聚合上发出本质上的变化。这些称为
领域事件
,并且对这些更改感兴趣的任何服务都可以侦听这些事件并在其域内采取相应的操作。这种方法避免了任何行为上的耦合:一个域不规定其他域应该做什么,以及时间耦合——一个过程的成功完成不依赖于同时可用的所有系统。当然,这意味着系统最终将保持一致。
在上面的示例中,订单服务发布了一个事件:订单已取消。订阅该事件的其他服务处理其各自的域功能:付款服务退还款项,库存服务调整项目的库存,依此类推。要确保此集成的可靠性和弹性的几点注意事项:
由于某些用例的性质,不一定总是可以使用基于事件的集成。请查看购物车服务和付款服务之间的集成。这是一个同步集成,因此我们需要注意一些事项。
这是行为耦合的一个示例——Cart服务可能从Payment服务中调用REST API,并指示其授权订单付款,而时间耦合则需要Payment服务用于Cart服务才能接受订单。
这种耦合减少了这些上下文的自治性,并且可能减少了不希望的依赖性。
有几种方法可以避免这种耦合,但是使用所有这些选项,我们将失去向客户提供即时反馈的能力。
-
将REST API转换为基于事件的集成。但是,如果支付服务仅公开REST API,则此选项可能不可用。
-
购物车服务立即接受订单,并且有一个批处理作业来接管订单并调用支付服务API。
-
购物车服务会产生一个本地事件,然后调用付款服务API。
在失败和上游依赖项(付款服务)不可用的情况下,将上述内容与重试结合使用可以使设计更具弹性。例如,在发生故障的情况下,可以通过事件或基于批次的重试来备份购物车和付款服务之间的同步集成。
这种方法会对客户体验产生额外的影响:客户可能输入了不正确的付款明细,并且当我们离线处理付款时,我们不会将其在线。否则,收回失败的付款可能会增加业务成本。但是,很有可能,购物车服务对于支付服务的不可用性或故障具有弹性,其缺点胜于缺点。例如,如果我们无法离线收款,我们可以通知客户。