微服务设计模式
什么是微服务?
相互独立但包含多个内部模块的子进程,服务之间采用网络调用(RPC)相互通信。
1| 独享数据库模式
特点:一个数据库对应一个微服务
优点:
- 更好的数据隔离、可扩展性和自治性。
- 每个微服务都可以独立地演化其数据模型,而不会影响其他服务。
- 每个微服务可以使用最适合的数据库。
- 团队开发之间耦合度降低
缺点:
- 写的问题:跨服务数据一致性问题(例如:订单+库存分布在两个服务中,单个服务中,利用数据库的事务就能解决@Transaction,分布在多个服务中,无法通过两个独立的数据库事务解决一致性问题-MQ半消息、2pc、3pc、seata、tcc),解决分布式事务头疼。
- 读的问题:跨服务的sql查询(在一个服务中,可以使用连接查询;跨服务就需要经过多次查询,再合并处理了,慢了,复杂了)
2| 事件溯源(Event Sourcing)模式
记录完整的过程(事件序列),就可以算出任意时间点的状态。(比如购物车开始有10件商品,又加入了5件,如果用数据库就是修改数据,但是事件源模式,就是记录开始10件,又加了5件…)
举例:
创建一个专门的服务来负责所有物化视图的更新。这个服务订阅所有相关的事件,并根据这些事件更新物化视图,以便获取最新的状态。
- 订单创建,发布消息
- 库存监听到,减少库存,发布库存减少的消息
- 支付处理,发布支持成功失败的消息
- 订单监听,修改状态为已支付
- (一般使用乐观锁去更新物化视图数据)
优势
- 有完整的事件序列(记录),有一些监管可以使用,还有比如用户在哪个功能停留了多久,什么时候退出系统,可以完整的监控到
挑战
由于需要事件版本控制、事件模式演化和处理长流程,因此复杂性增加。(当你引入新的字段(如订单备注)时,旧版本的事件没有这些字段。需要确保旧版本的事件在处理时不会因为缺少这些字段而导致错误,加了事件)
总结:我们一般使用MQ来实现。使用MQ 解耦、异步。
MQ数据一致性:
- 发送prepare消息到消息中间件
- 发送成功后,执行本地事务
- 如果事务执行成功,则commit,消息中间件将消息下发至消费端
- 如果事务执行失败,则回滚,消息中间件将这条prepare消息删除
- 消费端接收到消息进行消费,如果消费失败,则不断重试
3| 命令查询职责分离(CQRS)模式
主要用于提高应用程序的可伸缩性和响应性。它的核心思想是将处理命令(cud)与查询(q)的责任分。
- 命令侧(Command Side):负责处理所有改变应用状态的操作
- 查询侧(Query Side):负责处理所有从应用中检索数据的操
举例:
购物车举例。
传统购物车一张表,添加商品修改商品,查询都需要这张表来操作。
现在: 读与写命令分离,写的时候就操作写,然后发送事件,读的逻辑接收事件,并做更新,方便后面的读操作。
-
查询侧
- 数据存储:查询侧也有一个数据存储,也可以是一个缓存系统(如 Redis)。这个存储主要用于优化读取操作,比如快速获取购物车中的商品列表。
- 事件监听:查询侧监听命令侧发布的事件,并根据这些事件更新自己的数据存储。例如,当查询侧监听到
item_added
事件时,它会更新自己的数据存储,以反映最新的购物车状态
总结
通过使用 CQRS 模式,我们可以独立地优化写操作和读操作,从而提高系统的性能和响应能力。
一个长事务,之前支付成功,然后后端的配送订单也成功等等,全部成功之后这个长事务才能完整的结束。引入MQ后,每个小的事务成功之后,就成功了,保证最终一致性即可。
4| SAGA 模式
一种长事务管理模式。通过一系列有序的本地事务和相应的补偿事务来保证最终一致性。每个事务本地事务完成后立即提交,如果发生错误,则按照顺序执行相应的补偿事务以回滚到之前的状态。
一般有两种模式“:
- 编排模式:集中式的协调者管理和控制saga的执行,负责触发每个本地事务并处理失败后的补偿
- 协同模式:每个服务决定何时开始下一个本地事务,通过事件驱动的方式进行协调。
阿里开源Seata长事务解决方式,底层理论就是SAGA模式
5| 断路器(Circuit Breaker)模式
微服务通过同步调用其它服务,由于瞬时故障(网络等),可以尝试重新,如果服务不可用,还在不断访问,线程被阻塞,就会出现雪崩。
断路器模式,就是监控故障数量,决定继续请求还是直接默认返回。有三种状态,开启,关闭,半开。
阿里Sentinel 实现了断路器模式的核心思想,并且在其基础上增加了更多的功能
6| API 网关
反向代理: 根据请求(例如 URL 路径或请求参数)路由到相应的微服务。
横切关注点:
- 认证和授权,身份识别与访问控制
- 限速和节流
- 负载均衡
- log 日志、链路追踪、关联,集中式日志管理(服务之间的 transaction ID、错误日志等)
- Header、query 字符串 以及 claims 转义
- IP 白名单
优势
- • 客户端应用程序只需要与API 网关连接,相当于微服务对客户端来说是单个系统。
- • 减少了客户端和微服务之间的请求响应次数。
- • 提供了一个横切关注点,例如身份验证、授权和日志记录。
- • 充当安全网关,执行身份验证和授权策略。
挑战
- API网关本身容易形成单点故障,需额外的处理。
- 如果 API 网关执行大量处理,它可能会成为瓶颈
总结:
如果流量过大,gateway很容易造成性能瓶颈,但是gateway又作为入口,有很多期望的逻辑去做,这时候要评估逻辑是不是下方到各个服务去做,尽量让gateway轻快。
7|BFF模式
简单理解:本来这个页面要展示的数据需要3个接口来完成,现在后端封装成一个接口(接口聚合)了,减少了前后端直接的交互(某些场景下会使用,单不是所有)
8|边车模式
在每个微服务旁边部署一个代理服务(边车),来处理服务间的通信和其他附加功能
下单举例:
- 客户端发起请求:客户端(如Web应用)向订单服务的下单接口发送请求。
- 边车接收请求:边车代理接收请求,进行鉴权等。
- 记录日志:边车代理记录请求的日志信息。
- 转发请求:边车将请求转发给订单服务。
- 处理请求:订单服务处理请求并返回响应。
- 边车记录响应日志:边车记录响应的日志信息。
- 返回响应:边车将响应返回给客户端
还是解耦,维护性和灵活性都更高