Week10--- 课后总结
微服务
1.阿里早期微服务架构重构
单体应用的问题
一个war包里包含所有业务模块
打包的war包很大,编译,部署困难
代码分支管理困难
数据库连接耗尽
新增模块困难
2.web service 与企业级分布式服务
面向服务器的架构思想,最早应用的是webService,因为以下缺点导致没有在互联网项目中大规模应用:
臃肿的注册与发现机制
低效的XML序列号手段
开销相对较高的Http远程通信
复杂的部署与维护手段
3.微服务框架(Dubbo)架构
服务器提供者
在服务的容器中启动
服务容器根据配置把服务列表向服务中心提供
收到消费者的请求后,将结果打包通过远程模块返回给消费者
服务注册中心
维护服务器与服务列表的对应关系
服务消费者
通过服务接口调用服务,不依赖具体的实现
服务接口通过接口代理访问服务框架客户端
客户端先访问本地的服务提供列表,如果没有再访问远程的服务注册中心
通过自己的负载均衡模块确定要连接的具体ip和端口
通过远程通讯模块连接到远程服务的ip和端口,一般会使用tcp的长连接
服务框架客户端打包请求,通过远程通讯模块发送给服务提供者
接口访问代理将收到的结果包反序列化成class类,供服务接口调用
Dubbo协议
4.微服务框架需求
服务注册与发现
失效转移
负载均衡
高效的远程通信
对应用最少侵入
应用可以无感知地调用远程服务。
接口的版本管理
5.Service Mesh 服务网格
是一个基础设施层,用于处理服务间的通信
通常表现为一组轻量级的网络代理,与应用程序部署在一起,而对应用程序透明
6.微服务如何落地
业务先行,业务是最重要的,如果没有理清楚业务边界和依赖,很容易导致失败
业务耦合严重,逻辑复杂多变的系统进行微服务重构要谨慎
技术是手段不是目的
先有独立的模块,然后才有分布式的服务
要搞清楚实施微服务的目的是什么,不能为了微服务而做微服务。确定了目的在业务拆分的时候才能更好的做出选择,一个业务到底应该怎么拆分。
业务复用
开发边界
分布式集群提升性能
7.断路器
当某个服务出现故障,响应延迟或者失败率增加,继续调用这个服务就会导致调用者请求阻塞,资源消耗增加,进而出现服务级联失效,这时应该使用断路器对故障服务进行调用。
三种状态:关闭、打开,半开
8.关注的问题排序
需求是最重要的,用来解决什么问题
能否带来期望的价值
原则
最佳实践
选用工具
领域驱动设计DDD
1.DDD是为了实现领域模型的一种方法和手段
2.为什么需要DDD
需求零零散散,不断变更
实现需求的代码有多种方式可以放在这个模块,也可以放到别的模块,没有一个统一的模型维持其内在的逻辑一致性
领域模型要维持业务一致、产品一致、内部实现一致
代码实现要做到优雅,逻辑自洽
3.领域是什么
领域是一个组织所做的事情以及其所包含的一切。即组织的业务范围和做事方式,也是软件开发的目标范围。
领域驱动设计就是从领域出发,分析领域内模型及其关系,进而设计软件系统的方法。
4.传统的做法
事务脚本,随着业务的增加,会导致service层增大,业务逻辑复杂
也叫贫血模式,Service、dao中只有方法,没有数值成员变量;而方法调用时传递的数值,只有数据,没有方法;
5.领域模型
每个类复杂所有和自己相关的操作,比如Contract的计算是没有参数的,内部实现都是通过自己的成员变量来计算所得,具体成员变量的值则从外部获取,而不是将数据和操作分离开。
类似于面向对象的设计方式
又称为充血模式,相比贫血模式,领域模型的对象既包含对象的数据,又包含了计算逻辑。
设计好了领域模型,也就等于设计好了业务逻辑。
拆分子域
领域包含的范围过大,通常的做法是首先把领域拆分成子域,比如用户、商品、订单、库存、物流、发票等子域。
子域实际上就对应微服务。
限界上下文
在一个子域中,会创建一个概念上的领域边界。在这个边界内,任何领域对象都只表示特定于该边界内部的确切含义。这样的边界便称为限界上下文。
限界上下文和子域具有一对一的关系,用来控制子域的边界,保证子域内的概念统一。
比如商品在不同的子域(比如财务,订单,物流等)内代表不同的模型和业务流程,要在所有子域内实现统一并不现实,所以要限定上下文,保证在一个子域内商品的定义是一致的。
通常限界上下文对应一个组件或一个模块,或者一个微服务,一个子系统。
上下文映射图
不同的限界上下文会有各种交互,DDD中使用『上下文映射图』来设计这种关联和交互。
6.DDD的战术设计
实体
领域模型的对象也被称为实体
每个实体都是唯一的,具有一个唯一标识
实体可能发生变化,但唯一标识是不会变的
实体设计是DDD的核心所在
通过业务分析,识别出实体对象
通过业务逻辑设计实体的属性和方法
要把握实体的特征是什么
应该承担什么职责
不应该承担什么职责
分析的时候要把实体放到业务场景和限界上下文中,而不是考虑通常意义上的实体,想当然的觉得应该承担什么职责
值对象
并不是领域内的所有对象都应该被设计成实体,DDD推荐尽可能地将对象设计为值对象。
什么样的对象应该是值对象
有不变性
只是对一个实体的描述或者度量
比如住址
是对房子这个实体的描述
有不变性,如果住址变了,那就需要创建一个新的住址对象
与之相对的比如订单,订单的状态会经历创建,待支付,已支付,已发货等变化,当仍然是同一个订单
聚合
聚合是一些关联对象的集合,我们将其作为一个单元来处理数据更改
每个集合都有一个根和一个边界。
边界定义聚合内部的内容
根是聚合包含的单个特定实体
聚合根,将多个实体和值对象聚合在一起的实体,负责对外提供服务。外部如果要调用方法应该通过聚合根来实现,而不是调用其内部的对象。(比如车对象是聚合根,启动应该调用车的启动实现,而不是调用车引擎的启动来实现)。
命令与查询职责隔离(CQRS)
在服务层面实现读写分离,可以分别针对读写进行优化,是使用缓存还是消息队列
事件溯源
完整记录处理过程中的每次状态编号,并按时间序列进行持久化存储。
可以精确复现任何用户状态,进行复核审计
可以有效监控用户状态编号,在此基础上实现分布式事务。
可以方便的设置检查点,判断要做commit或rollback
7.DDD的分层设计
领域层中包含各种实体以及实现
领域实体的组合和调用,应该控制在应用层
用户接口层通过应用层调用领域层实现业务逻辑
8.DDD六边形架构
领域模型通过应用程序被封装成相对比较独立的模块,而不同的外部系统有不同的业务需求。
比如外部系统有的需要通过Http接口访问领域模型,有的需要通过Web Service接口访问模型,这时要做的就是为领域模型提供不同的适配器
总结
一个DDD重构的实践过程
战略设计可以独立于战术设计进行,战略设计有利于重构业务模型,梳理明确业务才能保证开发的顺利进行,即使不落地战术设计,对系统开发也有着重要的指导意义。
评论