Fescar源码阅读-解决分布式事务的利器

知其然,知其所以然!



目前分布式系统架构越来越流行,随之而来的分布式事务问题也越发凸显,但是对于这一难题,一直没有很好的解决方案,无论是基于消息的最终一致性、还是TCC模式都有相应的局限性和技术复杂度,都不能称为最佳方案。
阿里鼎鼎大名的GTS一直以来都被誉为解决分布式事务的利器,但是苦于其没有开源,对于大批码农来说GTS一直蒙着一层神秘面纱,到底它有着怎样的黑科技呢,好想知道。。。


出乎意料的是,2019年刚开始,阿里重磅开源了和GTS一脉相承的Fescar(这里确实要为阿里的开源精神点36个赞!),终于让我们能有有机会近距离接触Fescar。
了解Fescar,从源码开始!
本文作为开篇,作为阅读Fescar源码后的收获所得,权做笔记。
理解一个项目最快的方式是阅读它的官方文档,Fescar的官方文档目前还不是很完善,但是它的概述部分写的非常清晰明了,可以很快速的帮助我们理解整个产品的架构。
传送门:Fescar Guide


模块

Fescar项目的模块划分如下图(源码日期:2019-01-30):


3622524-c67013c79395b332.png
image.png
  • common
    喜闻乐见的common
  • config
    封装了系统配置的加载、获取、更新,如线程池的配置、commit缓冲区的配置等
  • core
    核心模块,定义了核心接口,包含系统交互模块、定义了各种报文结构、定义了消息的发送、接收、处理的核心接口
  • server
    TC的核心实现
  • rm-datasource
    关系型数据库RM的核心实现(Mysql)
  • tm
    TM的核心实现
  • spring、dubbo
    针对Spring和dubbo项目的接入适配层

TM、RM、TC

3622524-15bfc042c9711c6f.png
官网:TM、RM、TC

这张官方的图简单明了,展示了Fescar的三个核心概念模型:

  • Transaction Coordinator (TC): 事务协调器,维护全局事务的运行状态,负责协调并驱动全局事务的提交或回滚。
  • Transaction Manager (TM): 控制全局事务的边界,负责开启一个全局事务,并最终发起全局提交或全局回滚的决议。
  • Resource Manager (RM): 控制分支事务,负责分支注册、状态汇报,并接收事务协调器的指令,驱动分支(本地)事务的提交和回滚。

看看相关接口:

// 负责开启、提交、回滚全局事务
public interface TransactionManager {
    // 开启全局事务
    String begin(String applicationId, String transactionServiceGroup, String name, int timeout) throws TransactionException;
    // 提交
    GlobalStatus commit(String xid) throws TransactionException;
     //回滚
    GlobalStatus rollback(String xid) throws TransactionException;
     //获取事务状态
    GlobalStatus getStatus(String xid) throws TransactionException;
}
/**
 * 本地事务资源管理,管理本地事务的注册、报告,参与全局事务的提交回滚等
 */
public interface ResourceManager extends ResourceManagerInbound, ResourceManagerOutbound{
    
    //注册事务资源
    void registerResource(Resource resource);
    //注销事务资源
    void unregisterResource(Resource resource);
    
    //获取被当前RM管理的资源
    Map<String, Resource> getManagedResources();
}


public interface ResourceManagerInbound {
    //提交事务branch
    BranchStatus branchCommit(String xid, long branchId, String resourceId, String applicationData) throws TransactionException;
    //回滚事务branch
    BranchStatus branchRollback(String xid, long branchId, String resourceId, String applicationData) throws TransactionException;
}

public interface ResourceManagerOutbound {
    // 注册事务branch
    Long branchRegister(BranchType branchType, String resourceId, String clientId, String xid, String lockKeys) throws
        TransactionException;
    //报告事务branch状态
    void branchReport(String xid, long branchId, BranchStatus status, String applicationData) throws TransactionException;
    // 查询锁
    boolean lockQuery(BranchType branchType, String resourceId, String xid, String lockKeys) throws TransactionException;
}

/**
 * 被RM管理的资源,可加入全局事务
 */
public interface Resource {

    String getResourceGroupId();

    String getResourceId();
}

接口定义的很清楚,看名字就知道是什么作用了。
看完之后可能会有点奇怪,TM、RM都有核心接口、为什么没有TC的接口呢?
其实TC和(TM+RM)是分别作为服务端和客户端,他们实现的接口其实是一致的,只不过行为相反,同样一个接口,对于TM是出站的,则对于TC是入站;如果对于TM是入站则对于TC是出站;从而最终形成完整闭环。
比如TransactionManager#begin接口

  • 对于TM来说,作为客户端,在此接口中发送开启全局事务的请求到TC,并接受TC的返回;
  • 对于TC来说,作为服务端,在此接口中实现对全局事务Session的生成和存储,并返回XID给TM;

对于TM,RM的层次和责任划分,稍加整理,如下图:


3622524-c0d7b3890fa12781.png
FescarRM-define.png

官方提供的流程图,TM、RM和TC如何协作分工;

3622524-bc30523829fa5867.png
TM+RM+TC

先整理一下目前官方提供的实现:

  • TM:com.alibaba.fescar.tm.DefaultTransactionManager,实现了全局事务的开始、提交和回滚等。
  • RM:com.alibaba.fescar.rm.datasource.DataSourceManager,实现了对MYSQL数据库事务的资源管理;
  • Resource:com.alibaba.fescar.rm.datasource.DataSourceProxy,实现对MYSQL数据库代理。
  • TC:com.alibaba.fescar.server.coordinator.DefaultCorecom.alibaba.fescar.server.coordinator.DefaultCoordinator

DefaultCore 实现了TransactionManagerResourceManagerOutbound
DefaultCoordinator实现了ResourceManagerInbound


作为分布式系统,TM、RM和TC需要协作完成整个分布式事务的管控,自然是涉及到网络通信,Fescar基于Netty实现了系统间的交互。
下一篇我们先单独看看这部分的实现。Fescar源码阅读-RPC和消息

猜你喜欢

转载自blog.csdn.net/weixin_34323858/article/details/87042613