服务建模

设计方法

批注 2020-06-18 162701

好服务的标准

松耦合

高内聚

建模原则

bounded context

202002091623

模块与边界

模块的边界是绝佳的微服务候选者,但是新系统最好是先使用单体系统,过于早的边界划分,如果错了,代价会很大

业务功能

进行建模时,如果只考虑模型而不考虑具体业务功能,则就导致大量贫血的基于CRUD操作的服务

但是需要大量的业务知识,根据业务能力进行拆分的话,适合在初期,到了后期,随着系统体量增长,需要进一步拆分

逐步划分

一开始划分的是一些粗粒度的边界,接下来再对这些粗粒度边界继续划分成较细粒度的边界

业务逻辑设计与组织

组织模式:

屏幕截图 2021-01-22 102605

对于简单的业务逻辑,使用简单的解决方式:事务脚本模式

事务脚本模式只适用于简单的业务逻辑,是一种过程式的代码。当业务逻辑逐渐复杂,则就准备使用领域模型,这种模式是将业务逻辑组织为具有状态和行为的对象模型。

领域驱动设计是构建复杂业务逻辑最后利器,它提供了诸如entity valueobject factory repository service等概念都已经被现在的开发人员广泛采用,但对微服务最重要的概念,还是DDD中的聚合。

聚合模式

业务逻辑必须仔细设计,以保障全局的一致性,为了维护这种一致性,将各个领域模型组织成聚合,每组聚合就是一个边界,聚合外的模型只能通过聚合根来进行交流。

屏幕截图 2021-01-22 104934

一些规则:

聚合的粒度越细会越有扩展性,但粗一点的聚合也有降低编程工作量的好处,更粗的聚合,一次可以操作更多的模型。

屏幕截图 2021-01-22 110302

领域事件

领域事件指的是一般是过去的时候模型发生了某些状态变化或者执行了某些操作等。

领域事件由聚合负责发布。作为事件,同样也得满足事务的特征同时被可靠地发布。

事件发布之后,则可以通过消息代理被各方消费。

事件溯源

服务拆分

单体地狱

早期单体架构的好处:

  1. 应用开发简单
  2. 易于大规模更改
  3. 测试部署扩展简单

随着应用的不断丰富,单体暴露出了下列问题:

  1. 复杂性
  2. 影响开发效率
  3. 扩展难
  4. 错误无法隔离,软件变得不那么可靠

拆分单体

根据改变速度,团队结构,安全需求以及实现技术等对其进行分离

绞杀单体应用

拆分维度

停止挖掘

当开发新功能时不应该为旧单体应用添加新代码,最佳方法应该是将新功能开发成独立微服务

批注 2020-03-24 093946

前后端分离

将单体应用进行前后端分离,有两个好处:

抽出服务

与单体协作

单体重构的过程中,微服务肯定需要与单体进行协作,需要定义好一个它们之间的协作方式。

拆分服务

扩展

迁移

收缩:删除原先服务的无用代码

那么如何将对应的系统操作拆分为独立的服务?

根据业务能力

组织的业务是做什么。

从业务能力到服务的映射是一个非常主观的判断。围绕业务能力建模的好处在于最终的架构会趋于稳定。

利用DDD子域的概念来避免不同子领域复用相同术语所带来的混乱。

基于扩展性

将已经成熟和改动不大的服务拆分为稳定服务,将经常变化和迭代的服务拆分为变动服务

基于可靠性

将可靠性要求高的核心服务和可靠性要求低的非核心服务拆分开来,然后重点保证核心服务的高可用

基于性能需求

将性能要求高或者性能压力大的模块拆分出来,避免性能压力大的服务影响其他服务

服务API定义

依赖处理

数据库

外键

放弃,改用api调用来实现数据查询

共享数据

如果要求不苛刻,可以使用配置文件,否则使用一个专门的服务器来管理静态数据

独立出一个服务,专门来处理

需要重新审视设计,进行分表操作

数据库重构

先分离数据库再分离服务,虽然这样会破坏事务完整性,但是可以保证随时可以回退

事务

分离数据库之后,如何保证事务的安全性?

如果一个事务中的部分操作成功,部分操作失败,该如何?

引入这些都会增加系统的复杂性,最好的方式是避免这种跨服务的事务

报表问题

如果分离了数据库,那么如何解决需要所有数据的后台报表应用?

拆分单体到服务的难点