1.逃离单体地狱
2.解耦策略
软件架构
定义:
The software architecture of a computing system is the set of structures needed to reason about the system, which comprise software elements, relations among them, and properties of both.
计算机软件架构是合理化构建系统的结构集合,包括软件元素,相互关联,以及两者的属性;软件架构核心就是各个元素和他们之间的关系
分类
分层式架构
六边形架构
单体架构
微服务架构
如何定义微服务架构
提炼关键请求
- 创建关键类的抽象domain模型
- 创建模型的关键行为
- 定义行为 | 操作 | | | —- | —- | | 返回值 | | | 前置条件 | | | 后置条件 | |
分解服务
- 根据业务能力进行服务拆分
- 根据子域对象进行服务拆分(subdomain)
拆分服务的原则:
- 单一职责,定义的每个类只有一个职责
- 闭包原则
- 确定每个服务的API
- 确定服务入口
- 确定支持服务协作的所有api
服务分解的障碍
- 网络延迟
批处理,或者直接依赖,不用进程间通信
- 同步通信降低可用性
使用异步消息
- 维持数据的一致性
传统基于两阶段提交,后面使用saga
- 多个服务都会依赖的类
把这个类进行拆分,把每个服务依赖的部分放到服务中
3. 微服务架构进程间通信
概述
分类
按照通信机制分为: 同步(如REST,gRPC), 异步(如AMQP,STOMP)
按照消息格式分为: 可读性文本(如JSON,XML),高效二进制(如Avro,Protocol Buffers)
交互方式
一对一 | 一对多 | |
---|---|---|
同步模式 | 请求/响应 | 无 |
异步模式 | 异步请求/响应 单向通知 |
发布/订阅 发布/异步响应 |
微服务架构中定义API
API的更新演化
语义化版本控制
次要向后兼容的改变
主要不向后和兼容的改变
消息格式
按照消息格式分为: 可读性文本(如JSON,XML),高效二进制(如Avro,Protocol Buffers)
基于同步远程过程调用模式的通信
工作原理
客户端中的业务逻辑调用代理接口,这个接口由远程过程调用代理适配器类实现.调用代理向服务发出请求.请求由服务器适配器类处理,该类通过接口调用服务的业务逻辑.然后将回复发送回调用代理,该代理将结果返回给客户端的业务逻辑
应用
使用REST
REST成熟度模型
Level0
Level1
Level2
Level3
最流行的REST IDL是Open API规范
REST的优点
- 简单,熟悉
- 可以使用Postman和curl来测试HTTP API
- 直接支持请求/响应方式的通信
- 对防火墙友好
-
REST的缺点
只支持请求/响应方式的通信
- 可能导致可用性降低,客户端和服务端直接通信而没有代理缓冲
- 客户端必须知道服务实例的位置
- 单个请求获取多个资源比较复杂
- 很难实现复杂的更新操作
使用gRPC
gRPC是一种用于编写跨语言客户端和服务端的框架,是一种基于二进制消息的协议.gRPC使用Protocol Buffers作为消息格式
gRPC的优点
- 复杂更新操作的API很简单
- 高校紧凑的通信机制,特别在传输大量信息的时候
- 支持RPC和消息传递过程中使用双向流失消息方式
-
gRPC的缺点
前端需要做更多的工作,需要解析数据
- 旧式防火墙可能不支持HTTP/2
使用断路器模式除了局部故障
开发可靠的远程过程调用代理
- 设置网络超时
- 限制客户端发送请求的数量
-
从服务失效故障中恢复
使用服务发现
概念
服务发现是包含服务实例网络位置信息的一个数据库,关键组件是服务注册表
作用
服务实例启动和停止,服务发现机制会更新服务注册表
客户端调用服务时,服务发现机制会查询注册表获取服务实例列表,并请求路由到一个服务实例方式
服务及其客户直接与服务注册表交互
- 通过部署的基础设施了处理服务发现
应用层服务发现模式
自注册:服务实例向服务注册表注册自己
客户端发现模式:客户端从服务注册表检索可用服务实例的列表,并在他们之间进行负载均衡,实现有Eureka和Nocos
平台层服务发现模式
部署平台(docker和kubernetes)为每个服务提供DNS名称,虚拟IP地址和解析为VIP地址的DNS名称.客户端向DNS和VIP发送请求,部署平台自动将请求路由到一个可用服务实例.
基于异步消息模式的通信
4. 用saga管理事务
传统的分布式事务(2pc)不适合微服务架构,很多noSQL不支持XA
saga使用补偿事务来回滚所做出的的改变
saga的协调模式:
- 协同式saga:所有参与的服务,按顺序执行事务,如果一个服务异常,利用补偿性事务进行回滚
- 编排式saga:所有参与的服务和编排器类进行交互,由编排器类进行统一管理事务
解决隔离问题
隔离导致的问题:
- 丢失更新
- 脏读
- 不可重复读
对策(语义锁定):
- 语义锁:应用程序锁
- 交换式更新:把更新操作设计成可以按任何顺序执行
- 悲观视图:重新排序saga的步骤,以最大限度地降低业务风险
- 重读值:通过重写数据来防止脏写,以在覆盖数据之前验证它是否保持不变
- 版本文件:将更新记录下来,以便可以对它们重新排序
- 业务风险评级:使用每个请求的业务风险来动态选择并发机制