🚀 优质资源分享 🚀
学习路线指引(点击解锁) | 知识定位 | 人群定位 |
---|---|---|
🧡 Python实战微信订餐小程序 🧡 | 进阶级 | 本课程是python flask+微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一个全栈订餐系统。 |
💛Python量化交易实战💛 | 入门级 | 手把手带你打造一个易扩展、更安全、效率更高的量化交易系统 |
前言
虽然一直说想写一篇关于Saga模式,在多次尝试后不得不承认这玩意儿的仿制代码真不是我一个菜鸟就能完成的,所以还是妥协般地引用现成的Eventuate Tram Saga框架(虽然我对它一直很反感)和Seata的Saga模式。有一说一,我极其不愿意采用这种封装好的框架和解决方案对知识进行讲解,因为庞大的架构和源码对读者来说跨度太大,可是如果想把它内部流程讲清又要花费很大的精力进行详解,而且太考验文章的叙述文字功底了。
这有违我一直提倡的:“架构”是一种理论思想而非具体百搭的代码段。鉴于此,此章我会竭尽所能把基于框架的Saga模式讲解清晰,希望读者能够反复阅读,有不解的地方尽情在评论区询问。
Saga是什么?
分布式事务的挑战
在分布式系统中会把一个应用系统拆分为可独立部署的多个服务,因此需要服务与服务之间远程协作才能完成事务操作,这种分布式系统环境下的保证事务特性(ACID)的机制运转称之为分布式事务。
多个服务、数据库、消息代理之间在很多时候是必须维持数据一致性。特别是涉及金融交易的模块,即使可能只是出现1的偏差,也会因为蝴蝶效应而导致巨大损失。最原始的分布式事务管理的实施标准是XA模式(Seata AT和XA模式),其采用了两段式提交来保证事务中所有参与者都是健康且同时完成提交,或则在事务失败时同时进行回滚。
但XA模式也衍生出相关的问题:1、许多新技术包括NoSQL、RabbitMq并不支持XA标准的分布式事务;2、其性能上因为采用阻塞性协议,所有参与节点都是事务阻塞型的。当参与者占有公共资源时,其他第三方节点访问公共资源不得不处于阻塞状态,这就容易出现响应时间增长、死锁等问题;3、由于分布式事务采用的时同步进程间通信(发送请求就必须收到应答,否则不进行下次传输),这导致一旦分布式事务中的一个参与方出现问题就会让整个系统无法正常使用,降低了系统总体的可用性。
Eric Brewer在著名的CAP理论中证明了系统只要在一致性、可用性、分区容错性中保证两个就行。
分区容错性:在分布式系统中因为网络通讯故障而导致整个整体被分割成一个个分区,而这些分区仍可以继续对外供满足一致性和可用性的服务。(必要的)
可用性:系统一直处于可用状态,能正常响应数据,但是不保证响应数据为最新数据。
一致性:数据在多个副本之间能够保持一致的特性(Mysql主从表)。
今天,大部分架构师会倾向保证系统可用性,而将数据强制一致性的要求降低至满足最终一致便可。Saga正是为了解决微服务架构下数据一致性的问题,构建在松耦合、异步服务之上的机制。
Saga的机制
当本地事务完成时服务就会发布消息(图中Create order完成时发布消息),然后触发Saga中的下一个步骤(触发库存服务中预减库存)。通过消息发送
的方式可以确保所有参与服务之间的松耦合,也可以让整个业务流程实现异步通信,即使其中一些消息的接收方不可用,消息代理也会先进性缓存,直到消息被接受为止。
Saga的补偿式事务回滚
用八个字即可概括:有则继续,无则补偿。例如:当我从钱包
中拿出5块钱跟柜员说从冰箱
里拿一根巧克力甜筒,如果柜员发现冰箱
中有巧克力甜筒,就把甜筒拿出给我,把钱放入收银柜
中。如果柜员发现