微服务设计模式

微服务设计模式

什么是微服务?

相互独立但包含多个内部模块的子进程,服务之间采用网络调用(RPC)相互通信。

1| 独享数据库模式

特点:一个数据库对应一个微服务

优点
  • 更好的数据隔离、可扩展性和自治性。
  • 每个微服务都可以独立地演化其数据模型,而不会影响其他服务。
  • 每个微服务可以使用最适合的数据库。
  • 团队开发之间耦合度降低
缺点
  • 写的问题:跨服务数据一致性问题(例如:订单+库存分布在两个服务中,单个服务中,利用数据库的事务就能解决@Transaction,分布在多个服务中,无法通过两个独立的数据库事务解决一致性问题-MQ半消息、2pc、3pc、seata、tcc),解决分布式事务头疼。
  • 读的问题:跨服务的sql查询(在一个服务中,可以使用连接查询;跨服务就需要经过多次查询,再合并处理了,慢了,复杂了)
2| 事件溯源(Event Sourcing)模式

记录完整的过程(事件序列),就可以算出任意时间点的状态。(比如购物车开始有10件商品,又加入了5件,如果用数据库就是修改数据,但是事件源模式,就是记录开始10件,又加了5件...)

举例:

创建一个专门的服务来负责所有物化视图的更新。这个服务订阅所有相关的事件,并根据这些事件更新物化视图,以便获取最新的状态

  1. 订单创建,发布消息
  2. 库存监听到,减少库存,发布库存减少的消息
  3. 支付处理,发布支持成功失败的消息
  4. 订单监听,修改状态为已支付
  5. (一般使用乐观锁去更新物化视图数据)
优势
  • 有完整的事件序列(记录),有一些监管可以使用,还有比如用户在哪个功能停留了多久,什么时候退出系统,可以完整的监控到
挑战

由于需要事件版本控制、事件模式演化和处理长流程,因此复杂性增加。(当你引入新的字段(如订单备注)时,旧版本的事件没有这些字段。需要确保旧版本的事件在处理时不会因为缺少这些字段而导致错误,加了事件)

总结 :我们一般使用MQ来实现。使用MQ 解耦、异步

MQ数据一致性:

  1. 发送prepare消息到消息中间件
  2. 发送成功后,执行本地事务
  3. 如果事务执行成功,则commit,消息中间件将消息下发至消费端
  4. 如果事务执行失败,则回滚,消息中间件将这条prepare消息删除
  5. 消费端接收到消息进行消费,如果消费失败,则不断重试
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|边车模式

在每个微服务旁边部署一个代理服务(边车),来处理服务间的通信和其他附加功能

下单举例:

  1. 客户端发起请求:客户端(如Web应用)向订单服务的下单接口发送请求。
  2. 边车接收请求:边车代理接收请求,进行鉴权等。
  3. 记录日志:边车代理记录请求的日志信息。
  4. 转发请求:边车将请求转发给订单服务。
  5. 处理请求:订单服务处理请求并返回响应。
  6. 边车记录响应日志:边车记录响应的日志信息。
  7. 返回响应:边车将响应返回给客户端

还是解耦,维护性和灵活性都更高

相关推荐
工业甲酰苯胺3 小时前
分布式系统架构:服务容错
数据库·架构
Java程序之猿5 小时前
微服务分布式(一、项目初始化)
分布式·微服务·架构
Yvemil77 小时前
《开启微服务之旅:Spring Boot Web开发举例》(一)
前端·spring boot·微服务
小蜗牛慢慢爬行8 小时前
Hibernate、JPA、Spring DATA JPA、Hibernate 代理和架构
java·架构·hibernate
思忖小下9 小时前
梳理你的思路(从OOP到架构设计)_简介设计模式
设计模式·架构·eit
Yvemil711 小时前
《开启微服务之旅:Spring Boot Web开发》(二)
前端·spring boot·微服务
维李设论11 小时前
Node.js的Web服务在Nacos中的实践
前端·spring cloud·微服务·eureka·nacos·node.js·express
liyinuo201711 小时前
嵌入式(单片机方向)面试题总结
嵌入式硬件·设计模式·面试·设计规范
aaasssdddd9613 小时前
C++的封装(十四):《设计模式》这本书
数据结构·c++·设计模式