管理服务之间的依赖关系
在系统的各种组件之间,尤其是类、包、模块以及服务之间都可能存在依赖关系。依赖在某种程度上不可避免,但是过多的依赖势必会增加系统复杂性和降低代码维护性,从而成为团队开发的阻碍。在微服务架构中存在众多服务,服务之间需要管理相互之间的依赖关系。1. 构建无环依赖架构依赖关系有三种基本的表现形式,其中类似Service1依赖于Service2这种直接依赖最容易识别和管理(见下图a);间接依赖即直接...
在系统的各种组件之间,尤其是类、包、模块以及服务之间都可能存在依赖关系。依赖在某种程度上不可避免,但是过多的依赖势必会增加系统复杂性和降低代码维护性,从而成为团队开发的阻碍。在微服务架构中存在众多服务,服务之间需要管理相互之间的依赖关系。
1. 构建无环依赖架构
依赖关系有三种基本的表现形式,其中类似Service1依赖于Service2这种直接依赖最容易识别和管理(见下图a);间接依赖即直接依赖关系的衍生,当Service1依赖Service2,而Service2又依赖Service3时,Service1就与Service3发生了间接依赖关系(见下图b);而所谓循环依赖就是Service1和Service2之间相互依赖(见下图c),循环依赖有时候并不像图中描述的那么容易识别,因为产生循环依赖的多个组件之间可能同时存在各种直接和间接依赖关系。
下图就是一个循环依赖的例子,User对象可以创建Order对象并保持Order对象列表,而Order对象同样需要使用User对象,并根据User对象中的打折(Discount)信息计算Order金额,这样对象User和Order之间就存在循环依赖关系。
根据无环依赖原则(Acyclic Dependencies Principle,ADP),系统设计中不应该存在循环依赖,该条原则对于微服务架构而言同样适用。消除循环依赖的基本思路就是通过在两个相互循环依赖的组件之间添加中间层,变循环依赖为间接依赖。有三种策略可以做到这一点,分别是上移、下移和回调。下面我们将通过基于组件的具体示例介绍这三个策略,因为服务由一个或多个组件构成,所以其适用于服务之间的关系管理。
(1)上移
关系上移意味着把两个相互依赖组件中的交互部分抽象出来形成一个新的组件,而新组件同时包含着原有两个组件的引用,这样就把循环依赖关系剥离出来并上升到一个更高层次的组件中。如下图就是使用上移策略对User和Order原始关系进行重构的结果,我们引入了一个新的组件Mediator,并通过其提供的payOrder方法对循环依赖进行了剥离,该方法同时使用Order和User作为参数并实现了Order中根据User的打折信息进行金额计算的业务逻辑。Mediator组件消除了Order中原有对User的依赖关系并在依赖关系上处于User和Order的上层。
(2)下移
关系下移策略与上移策略切入点刚好相反。我们同样针对User和Order的循环依赖关系进行重构,重构的方法是抽象出一个Calculator组件专门包含打折信息的金额计算方法,该Calculator由User创建,并注入到Order的pay方法中去(见下图)。通过这种方式,原有的Order对User的依赖关系就转变为Order对Calculator的依赖关系,而User因为是Calculator的创建者同样依赖于Calculator,这种生成一个位于User和Order之下但能同样消除Order中原有对User的依赖关系的组件的策略,就称之为下移。
(3)回调
回调(Callback)本质上就是一种双向调用模式,也就是说,被调用方在被调用的同时也会调用对方。在面向对象的语言中,回调通常是通过接口或抽象类的方式来实现。下图就是通过回调机制进行依赖关系重构后的结果。我们抽象出一个Calculator接口用于封装金额计算逻辑,该接口与Order处于同一层次,而User则实现了该接口,这样Order对User的依赖就转变成Order对Calculator接口的依赖,也就是把对User的直接依赖转变成了间接依赖。通过依赖注入机制,我们可以很容易的实现Order和User之间的有效交互。
2. 弱依赖与强依赖
从故障容忍度的角度来看,服务之间的依赖关系又可以分为弱依赖与强依赖。如果某个微服务无法正常提供服务,则依赖它的整个业务流程无法正常执行下去,那么即为强依赖关系,也就是说,强依赖关系是服务正常运转的基本单元。而弱依赖则没有这样的限制,对于如消息发送等服务,如果该服务无法正常提供功能,核心业务流程同样可以正常运行。
对强依赖和弱依赖对应的消息进行区分可以得到可靠消息和非可靠消息。可靠消息必须通过系统级的方式进行保障,使得关键服务能够运行,而对非可靠消息,则可以简单容忍丢失行为,使得整体系统的复杂度降低。通常,我们可以对弱依赖设置开关,其目的是在极端资源瓶颈出现的时候,使得业务系统能够丢弃一些非核心服务从而保全更关键的核心服务。关于可靠事件以及服务依赖关系所涉及的服务分级、限流和降级操作我们将在后面的文章中进一步展开讨论。
如果对文章感兴趣,可以关注我的微信公众号:程序员向架构师转型,或扫描下面的二维码。
我出版了《系统架构设计:程序员向架构师转型之路》、《向技术管理者转型:软件开发人员跨越行业、技术、管理的转型思维与实践》、《微服务设计原理与架构》、《微服务架构实战》等书籍,并翻译有《深入RabbitMQ》和《Spring5响应式编程实战》,欢迎交流。
更多推荐
所有评论(0)