横向拆分(横向分层)
首先我按照分层架构的思想以纵向维度拆分,通俗点就是按照自定向下的按照各层职责进行分解,主要共分5层,UI层、聚合API服务层、基础业务API服务层、基础设施层、数据库层。
调用链路自顶往下,用户-->UI-->API网关-->聚合API服务-->Consul+Consul Template+Nginx-->业务API服务-->数据库
UI层
依赖于聚合API服务层,操作与接口11对应,主要负责可见即可得的工作:数据展示、交互动画等。
入站API网关
主要负责聚合API服务层内外网隔离、入站规则控制,防止外部大流量冲垮内部服务。
聚合API服务层
被UI层依赖,依赖于基础业务API服务层,主要负责基础业务API服务层的接口的逻辑组合,不直连数据库,可通过API网关暴露给UI层调用。
注册服务中心
记录基础业务API服务层的服务IP列表,内网使用,衔接聚合API服务层与基础业务API服务层。
基础业务API服务层,
被聚合API服务层依赖,依赖于数据库层,可做具体的数据库读写处理,内网使用,同层服务之间不互相依赖引用。
数据库层
包括非关系型数据库与关系型数据库。
基础设施服务层
可被所有层都依赖,如果被UI层依赖则通过API网关暴露,如果被内网服务依赖则通过注册发现,可直连数据库。
出站API网关
主要负责基础设施服务层内外网隔离,转发第三方开放API请求,出站规则控制,防止被无法把控的第三方服务而拖垮内部服务。
纵向拆分(纵向切割)
接下来,我们可以通过DDD进行服务的切割,通俗点描述就是将同一个较大的服务拆解成为多个较小的服务。
那么究竟要根据什么样的信息和过程进行拆解呢?有一个工作坊叫作"事件风暴",事件风暴是一个从拆解到整合的过程,过程中需要领域专家(需求提出者)和技术实践者协作完成领域建模。
一般采用场景分析和用例分析尽可能分解出领域对象(实体、命令、事件),可以从交流的过程中提取出领域专家(需求提出者)口中的名词、动作、触发事件等,这是一个拆解的过程。
将以上沟通后的结果进行重新梳理,寻找他们的关系进行汇聚,形成聚合与界限上下文,这就是一个整合的过程。
一个微服务粒度可以粗与界限上下文一致,粒度可以细化到一个聚合。
举个例子:
我们平台拥有三种不同业务领域的系统:客户中心、企业管理系统、内部管理系统。
那么,聚合API服务层则拥有客户系统API服务、企业管理系统API服务,内部管理系统API服务。
客户中心的拥有客户信息管理、支付、订单管理等业务模块。
企业管理系统拥有订单管理、权限管理、支付、仓储等业务模块。
内部管理系统拥有权限管理、报表、账户管理等业务模块。
所有系统涉及到自定义订单号、消息推送等业务。
从以上得知,核心域包括仓储、订单业务、客户信息。通用域包括权限管理、账户认证、支付模块、消息推送等。支撑域包括自定义订单号。
因此基础业务API层可以划分:仓储API服务、订单API服务、客户API服务、权限API服务、认证API服务,支付API服务。
基础设施API层可以划分:ID发号API服务,消息推送API服务。
后来多次跟产品经理沟通后得知,仓储服务在某个场景下需要把修改订单服务的状态,那么这里有个触发事件,而且是跨微服务的,因此引入了基于消息的最终一致性的分布式事务进行解决。
如果随着业务继续扩大,团队人数增多,则可以更加的细分,例如仓储拆分成快运、集运等。支付拆分成微信支付、支付宝等。
项目示例
上一篇《.Net微服务实战之技术选型篇》我整理了我们公司使用的框架开源到了github,这次我拿了部分业务项目作为示例并上传了。
https://github.com/SkyChenSky/Sikiro
首先想说明几点:
1.这个不是标准,只是针对我们公司情况取舍后的结果,每个公司的业务有复杂有简单大家视情况完善自己的项目。
2.为了保护公司原有的业务隐私,我做了部分逻辑的删除,所以大家如果看到不完整的逻辑是正常现象。
3.希望大家把思维放高,不要死抠细节,求同存异。
4.代码在原有的基础上修改了名称和引用路径会有变化,如果有问题随时在评论和github反馈给我。