3、微服务拆分

3.1优秀的微服务

好的微服务,有两个最重要的概念:高内聚与低耦合。架构


其实不仅有微服务,软件设计的追求也在此,对于这个概念,相信在学习开发的初始阶段就会据说,但并非全部人据说后就会理解,咱们在研发经验逐步累积到必定程度后,就会真正想清楚这两个概念背后的含义。微服务

 

3.2高内聚

把相关的行为汇集到一块儿,把不相关的行为放在别处。这个说法与SRP很像,由于若是你想要改变某个行为的话,最好可以只在一个地方进行修改,而后就能够尽快发布。学习


好的微服务要基于这一点,将相关的业务集中到一个微服务中实现。要作到准确内聚,就要找到需求边界,而这个边界有多是慢慢摸索出来的。测试

 

3.3低耦合

若是你的微服务作到了低耦合,那么修改一个服务就不须要修改另外一个服务。spa


那么什么会致使高耦合呢?一个典型的错误是,在作服务之间的集成时,修改一个服务会致使其消费者也进行修改。一个号的服务应该尽量少的知道与之协做的那些服务的信息,应该尽可能限制服务之间不一样形式的调用,过分通讯会致使高耦合。这个说法与Law of Demeter很像,其实,设计六大原则就是将高内聚低耦合完整的抽象出来了。设计

3.4共享模型与隐藏模型

任何一个特性的行业业务,都包含着多个上下文边界,所谓的上下文边界,就是各个业务模块之间的交互点,在程序中就是模块的接口。 接口


一个业务模块,正常来讲有两部分模型(实体)组成,一部分不须要与外部通讯,另外一部分则须要。
让咱们来看一个具体的例子:开发


 
图中,财务与仓库两个模块是两个独立的界限上下文,他们都有明确的对外接口(存货报告、工资单),也有只须要本身知道的细节(铲车、计算器)。软件


财务模块不须要知道仓库模块的内部细节,但它须要知道库存水平,以便于更新帐户,为了算出公司的估值,须要知道库存信息。程序


在日常,设计者会将库存信息做为对外接口的模型,将其变成模块间的共享模型,这种作法实际上是不太可取的,不要盲目的把库存信息内容所有都暴露出去。仓库模块应该设计暴露给财务模块的库存信息(库存项),有时候,同一个名字在不一样的上下文中有着彻底不一样的含义。


总结起来就是,应该共享特定的模型,而不该该共享内部模型。


作到上述事情,能够大量避免高耦合,并且在明确了各个边界,能够实现高内聚。因此,一旦你发现了业务模块的边界和模型,一旦要对其进行建模,同时使用共享模型和内部模型。


对于一个新系统或新业务领域来讲,能够先使用一段时间单体架构,由于若是服务之间的边界搞错了,会付出很大的代价,因此最好可以等到系统稳定下来、熟悉业务后,在对单体架构进行微服务的拆分。


当你在思考业务边界时,不该该从共享数据的角度来考虑,而应该从这些业务边界可以提供的功能来考虑。好比,仓库的一个功能是提供当前的库存清单,财务可以提供月末帐目或者为一个员工建立工资单。为了实现这些功能,可能须要交换存储信息的模型。若是只考虑模型,你有可能只设计出一个贫血服务(只基于CRUD的服务)。

 

3.5拆分的建议

新项目开始阶段,你会识别出一些粗颗粒度的业务边界,而这些业务中可能会包含另外一些业务。好比,能够把库存模块分解为不一样的子模块:订单模块,库存管理模块,货物接收等。


在被外部服务调用时,这些嵌套的子模块对外部是不可见的。例如:


 
但有时候你会认为,高层次的业务模块不该该被显示地建模成一个服务,应该把子模块拆分出来:
 
一般很难说那种规则更合理,可是应该根据组织结构来决定,若是订单、库存等由不一样的团队或者我的维护,那么他们大概都会但愿这些服务是顶层服务。单若是他们由一个团队或我的来维护,那么使用嵌套结构会更合理。


另外一种倾向于嵌套方法的缘由是,它可使得架构更方便的测试,当测试仓库的消费者时,不须要对仓库中的每一个服务进行打桩,只专一于粗粒度的API测试便可。


基于行业业务的软件建模不该该止步于业务边界的拆分,在组织内部共享的那么相同的术语和想法,也应该被反映到服务的接口上。沟通、通讯形式在整个组织范围内都很是重要。

 

3.6小结

总结了什么是好的服务,以及如何作到高内聚与低耦合。


而且聊到了在进行微服务的拆分时,应该先基于业务功能去拆分,这样天然而然会得出一个正确的共享模型,然后,对服务的拆分颗粒度进行了建议。

若想进一步了解如何准确的拆分业务功能,能够读一读Eric Evans的《领域驱动设计》一书。