最近把我所做的一个项目改成分布式的,把几个组件都跑了一篇,对于分布式算是有了初步的了解。发现很多博客都是在用十分简单的hello world来做例子,的确这对于学习是比较不错的,但是太不实用了。例如在我的这个项目(贵金属递延交易系统(联合工行、中行、建行举办的一个贵金属交易大赛的系统))中,在委托单成交的时候,需要扣除用户的账户余额,但是这是两个不隶属于同一个系统,那么如何保证下单和扣减金额的原子操作呢,于是今天我们就来具体的聊一下分布式事务。
ps:学习的时候建议结合实际的例子来改造,这样带着思考的同时可以发现,在实际改造的过程中你去碰到的坑,这样整个一套流程下来,基本上也就可以算是一个完整的项目经验了。笔者在改造的过程中分别遇到过,节点多机器内存不够等问题,想要关注去深入的使用却需要安装一堆的东西。下篇博文将介绍如何解析这些问题,预告:使用docker来跑微服务中的服务、使用docker来跑rabbitmq集群
一、何为cap?
- c consistency:一致性
- a available :可用性
- p partition :分区容错性
cap理论主要讲的是在分布式系统当中,最多是能实现上面的两点,二由于当前网络或者硬件的问题肯定会出现延迟丢包的问题,所以其中的分区容错性使我们必须要考虑的,所以我们需要在c和a中进行权衡。例如:在服务发现当中我们就可以舍弃c去保证a和p,eureka便是这样来实现的。
二、分布式事务:
在关系型数据库当中,我们有ACID来实现事务,但是在分布式当中,每个数据库节点是物理分离的,或者每个事物的发起点即分布式中的单个服务需要要组合多个事务,而这多个事务并不在一个系统中,所以就需要我们使用一定的策略来保证这一个大的事务的执行。下面我们就聊一聊现在流行的一些策略。
2.1 、2PC(XA)
image.png- 第一阶段:
1、协调者向所有的参与者节点询问是否可以进行操作,并等待所有参与者的应答
2、参与者执行询问发起的操作,写入日志Redo和Undo,但不执行事务
3、各个参与者相应事务管理器的询问,并发送是否同意 - 第二阶段:
在响应都是成功的情况下,否则直接回滚
1、各协调者想所有参者发起是否提交的请求
2、参与者执行提交操作,并释放整个事务期间的资源,
3、参与者相应是否完成的消息
如果任意一节点无法完成操作或者响应时间超时,则向所有节点发送回滚操作
优缺点:
优点:原理简单,易实现
缺点:同步阻塞、协调者单点问题,如果协调者跪了,部分参与者收到commit消息,出现数据不一致。事务整个周期被延长,负载过大不适用于互联网的高并发操作。
现在很多关系型数据就是通过这个来实现的(可以在网上搜索XA事务了解)
2.1.1 TXC
在2pc中有单点故障,TXC引入协调者集群,具体的可以了解一下 支付宝 分布式事务服务 DTS 二
2.2、TCC
tcc是基于2pc的一种改进
核心思想为:基于每一个事务的操作,都注册一个与其对应的确认和补偿(撤销)操作:
1、try:主要对业务做检测以及资源预留
2、confirm:阶段主要应对系统做确认提交,try阶段成功之后执行confirm
3、cancel:阶段主要是应对执行业务层错误是的一个回滚
优缺点:
优点:和2pc比起来实现流程要简单一些,但是数据一致性要比2pc差一点
缺点:在2、3阶段都有可能失败,需要在应用层定义补偿方案。有很多时候这种方案并不太好定义
2.3、3pc
关于3pc在这里就不在介绍了,好像现在只是一个理论,并没有具体的应用
2.4、通过MQ来解决分布式事务
image.png我想正常的情况依据这个图大家都能看懂,那下面我们讨论一下异常的情况
- 1、A 在提交事务后,没来得及发消息就挂掉了,在A节点重新启动后查询没有关联消息的记录,然后重发消息
- 2、如果B节点挂掉了,这个没有关系的,除非整个B节点集群挂掉了,否则rabbitmq可以通过重试机制,
这个是我们目前理解的成熟的一个解决方案。现在网上所能搜到的都是基本大谈2pc、tcc等,基本没有什么解决方案,要么也就一笔带过。当然此篇博文也是博主自己思索的,如果有错误还请指正。
网友评论