9:微服务
一:为什么
问题:巨无霸应用系统带来的问题
编译部署困难
代码分支管理困难
数据库链接耗尽
新增业务困难
解决方案:拆分,将模块独立部署,降低系统耦合
纵向拆分
横向拆分
二:微服务框架
webservice 的缺点
臃肿的注册发现机制
低效的 XML 序列化手段
开销相对较高的 HTTP 通信
复杂的部署与维护手段
微服务框架需求
失效转移
负载均衡
高效的远程通信
对应用的最少侵入
版本管理
为了应对快速变化的需求,服务版本升级不可避免,如果仅仅是服务实现升级
微服务框架 Dubbo 架构
serviceMesh 服务网格
是一个基础设施层,用于处理服务间的通信,哦通常表现为一组轻量级网络代理,他们与应用程序部署在一起,而对应用程序透明
sideCar 模式
微服务架构实践
落地
业务现行,先理顺业务边界和依赖,技术是手段而不是目的
现有独立的模块,后有分布式服务
业务耦合验证,逻辑复杂多变的系统进行微服务重构要谨慎
要搞清楚实时微服务的目的是什么,业务复用?开发边界清晰?分布式集群性能提升?
命令与查询职责隔离 CQRS
在服务接口层面将查询与命令(写)隔离,实现服务层的读写分离
更清晰的领域模型
针对读写分别优化,实现更好的性能
查询服务不会修改数据,更好的保护数据
事件溯源
将用户请求处理过程中的每次状态变化记录到日志,并按时间序列进行持久化存储
利用事件溯源,可以精确复现任何用户状态,进行复核审计
利用事件溯源,可以有效监控哦用户状态变化,并在此基础上进行分布式事务
断路器
当某个服务出现故障,响应延迟或者失败增加,继续调用这个服务会导致调用请求阻塞,资源消耗增加,进而出现服务级联失效这种情况使用断路器阻断对失败服务的调用
服务重试以及调用延时
上游调用时间要大于下游调用时间之和
RPC 协议实现原理
远程过程调用
通讯协议
在电信领域中是指在任何物理介质中允许两个或者多个在传输系统中的终端之间传播信息的系统标准也是指计算机通讯或者网络设备的共同语言
协议的两部分
网络通信协议:TCP?UDP
编码传输协议:二进制、文本、协议头格式
常见私有协议模式
Dubbo 通讯协议
解码 response
解码 Request
利用 RequestId 避免对头阻塞
SOFA-RPC 通讯协议-Bolt 协议
微服务网关
基于网关的微服务架构
网关的作用
网关管道技术
网关本身没有什么业务,主要职责是做各种校验与拦截,这些职责可以通过管道技术链接起来:责任链模式
Flower 异步网关与异步微服务框架
二:DDD
为什么需要 DDD
本质还是职责不清晰,导致的一团乱麻
战略设计部分
领域是一个组织所做的事情以及其包含的一切,通俗地说,就是组织的业务范围和做事方式,也是软件开发的目标范围
领域驱动设计就是从领域出发分析领域内模型以及其关系,进而设计软件系统的方法
子域
限界上下文
一个子域中,会创建一个概念上的领域边界,在这个边界中,任何领域对象都只是表示该边界内部的确且含义。其和子域有一对一的关系,用来控制子域的边界。通常一个限界上下文就是一个组件或者一个模块或者一个微服务
上下文映射图
不同限界上下文,即不同子域之间会有各种交互合作,使用映射图来设计这种交互
战术设计部分
实体
领域模型对象,每个实体都是唯一的。其设计是 DDD 核心所在,
首先通过业务分析,识别出实体对象,
然后通过相关业务逻辑设计实体的属性和方法。
这里最重要的是把我实体的特征是什么,实体应该承担什么责任,不应该承担什么职责,分析的是时候要放在业务场景和界限上下文中。
值对象
DDD 推荐尽可能将对象设计为值对象。比如住址
他的特点是不变性,变了就是一个新的地址。
聚合
一个关联对象的集合,将其作为一个单元来处理数据的更改。每个集合都有一个跟和一个边界。边界定义了聚合内部的内容,根是聚合中包含的单个特定实体
聚合根:将多个实体和值对象聚合在一个的实体
CQRS
在服务接口层面将查询与命令隔离,实现服务读写分离
更清晰的领域模型
针对读写分别优化,实现更好的性能
查询服务不会修改,可以更好地保护数据
事件溯源
将用户请求处理过程中的每次状态变化都记录到事件日志中,并按时间进行持久化
架构 u
分层
领域实体的组合调用和事务控制在应用层
用户接口层->应用层->领域层
六边形
领域模型,通过应用程序封装成一个相对独立的模块,不同的外部系统通过不同的适配器和领域模型交互。
只需要为不同访问接口提供不同的适配器就可以了
三:组件设计原则
组件内聚原则:主要讨论哪类应该聚合在同一个组件中,以便组件既能提供相对完整的功能,又不至于太过庞大
复用发布等同原则
软件复用的最小粒度应该等同于其发布的最小粒度。你想别人怎样的粒度使用,你就要以怎样的粒度发布。这个粒度就是组件了。既是复用的粒度,也是发布的粒度
所以提交代码的版本号一般都有约定:主版本好-次版本号-修订号
主版本:发生了步向前兼容的重大修订
次版本:组件进行了重要的功能修订,并向前兼容
修订号:不重要的功能修订
共同封闭原则
我们应该将那些会同时修改,并且为了相同目的而修改的类放到同一个组件中,将不会同时修改,并且不会为了相同目的而修改的类放到不同的组件中
组件的目的是为了复用,然而,开发中引发的我问题,恰恰在于组件的可维护性。如果组件必须经历各种变更,那么最好不要涉及其他组件,相关变更都在同一个组件中。这样当变更发生的时候只需要重新发布这个组件就可以了。
共同复用原则
不要强迫一个组件的用户依赖他们不需要的东西
这个原则一方面说,我们应该互相依赖,共同复用的类放在一个组件里。
另一个方面,说明,如果不是被共同依赖的类,就不应该放在一个组件中。
组件耦合原则
组件应该包含那些功能和类,即耦合关系应该如何设计
无循环依赖
组件依赖关系中不应该出现环
稳定依赖
组件依赖关系必须执行更稳定的方向。经常变更的就是不稳定的,所以不稳定的应该依赖稳定的组件
稳定抽象
一个组件的抽象化程度应该与其稳定程度一致。即一个稳定的组件应该是抽象的,不稳定的应该是具体的
对开发的指导意义即 使用接口隔离变化
评论