专栏名称: CSDN
CSDN精彩内容每日推荐。我们关注IT产品研发背后的那些人、技术和故事。
目录
相关文章推荐
新浪科技  ·  #蔚来一季度交付同比增长超40%# ... ·  2 天前  
新浪科技  ·  【#特斯拉财富美国500强排名首次下滑##微 ... ·  2 天前  
51好读  ›  专栏  ›  CSDN

业务视角下的微服务架构设计实例

CSDN  · 公众号  · 科技媒体  · 2017-06-05 10:51

正文

请到「今天看啥」查看全文



下面我们将从几个方面展开这个话题。

不要从数据库开始建模


传统软件开发中,数据模型被认为是整个系统的核心,业务逻辑仅仅是对数据的CRUD加上简单的计算呈现。有些项目团队的架构评审会花很多时间来讨论系统庞大的ER图(实体关系图)设计。但在微服务架构设计时,ER图并非最佳选择,特别是在服务划分时采用ER图进行建模甚至是十分有害的。


在领域驱动设计的实践中,有一个和ER图建模有些相似的环节,叫做“领域建模”。相比ER图建模通常只有开发人员参与,并从数据表的角度考虑模型的方法,领域建模的过程需要由产品的业务人员和核心开发人员共同参与,先梳理用户场景,然后从业务领域角度,逐步确定场景中的实体、关联和聚合等元素。其中的“实体、关联”与ER图中的“实体、关系”有些相似,但含义并不一致。领域模型中的“实体”本质上是业务场景中需要被持久化存储的对象,但存储方式不一定是数据库,更不一定是关系型数据库,而ER图中的“实体”最终对应的就是关系型数据库的表。领域模型中的“关联”是两个实体在业务上下文之间有业务含义的联系,而ER图中的“关系”只的是两张表之间的一个关联外键。


那么,使用ER图给微服务建模会存在什么问题呢?


首先,ER图设计时假定了使用的是关系型的数据库。微服务的一个特点在于它支持异构架构,系统的不同部分,依据实际需要可选择不同的编程语言、框架以及数据库的类型。关系型数据库采用平面表的结构,如果有两类嵌套关系的对象,只能使用关联表来表达两个实体之间的关系,然后通过复杂的SQL语句在查询时将多个表拼成更大的平面表,最后在业务代码里再分解到各个独立的对象里去。这些单独的表又可能在其他地方与另一个表存在关联查询。这样设计出来的表结构的冗余很低,且使用非常灵活,但正是这种灵活性往导致系统中多个业务逻辑表出现错中缠绕的关系,从而使剥离单独服务进行异构设计变得困难。


其次,ER图还会导致实体相似的不同业务逻辑在设计时被耦合在一起。举一个具体的例子,在汽车代理销售系统中,不同品牌汽车的购买流程后端实际上分别对接的是完全不同的分销渠道系统和逻辑流程,但它们在用户视图上所需要的信息比较一致,因此存储的数据结构也比较相似。这个系统在最初设计时采用了ER图的方式建模,由于ER图模型不关心业务层面上的东西,不同品牌汽车的实体数据看上去都是一种类型的数据,仅仅是一个品牌字段的差异而已,因此被理所当然的设计成了同一张表。上层逻辑实现的时候使用了大量的if-else语句来区分各种品牌的购买流程,结果使得多条完全不同的业务线糅合在同一个上下文里,后来的开发非常容易在这里错改、漏改代码。若当初使用的是领域建模,则不同的购车流程会自然的被划分到各种不同的用户场景,即使它们在数据结构上看起来基本相同,也会被识别为两个独立的上下文,这就会使得未来划分服务时能够更加容易。


最后,ER图设计的架构会使得系统的模块之间倾向于使用数据库集成,而非API集成。在ER图中没有明确划分模块和表的所有权关系,所有的数据表对所有的模块都是可见的,倘若不加额外约束,各个模块便都会轻易的读写其中的内容。数据集成并不会直接导致服务无法拆分,但由于数据的所有权不清晰,十分容易引发的意想不到的状况。还是举销售平台的例子,在ER图建模得到的模型中,有一张与购买记录相关的表。在一次销售业务的代码更新中,对购买结果的增加了字段,在测试过程中没有发现问题,结果上线几天以后,由于售后服务也在修改这个表而导致出现了脏数据,造成难以排查的故障。


当然,我们并非要完全否认ER图建模的价值,只不过通过数据库角度建立模型的过程容易倾向于设计出庞大的单体应用,因而不太适应于服务划分的目的。







请到「今天看啥」查看全文