知其然,知其所以然!
目前分布式系统架构越来越流行,随之而来的分布式事务问题也越发凸显,但是对于这一难题,一直没有很好的解决方案,无论是基于消息的最终一致性、还是TCC模式都有相应的局限性和技术复杂度,都不能称为最佳方案。
阿里鼎鼎大名的GTS一直以来都被誉为解决分布式事务的利器,但是苦于其没有开源,对于大批码农来说GTS一直蒙着一层神秘面纱,到底它有着怎样的黑科技呢,好想知道。。。
出乎意料的是,2019年刚开始,阿里重磅开源了和GTS一脉相承的Fescar(这里确实要为阿里的开源精神点36个赞!),终于让我们能有有机会近距离接触Fescar。
了解Fescar,从源码开始!
本文作为开篇,作为阅读Fescar源码后的收获所得,权做笔记。
理解一个项目最快的方式是阅读它的官方文档,Fescar的官方文档目前还不是很完善,但是它的概述部分写的非常清晰明了,可以很快速的帮助我们理解整个产品的架构。
传送门:Fescar Guide
模块
Fescar项目的模块划分如下图(源码日期:2019-01-30):
- common
喜闻乐见的common - config
封装了系统配置的加载、获取、更新,如线程池的配置、commit缓冲区的配置等 - core
核心模块,定义了核心接口,包含系统交互模块、定义了各种报文结构、定义了消息的发送、接收、处理的核心接口 - server
TC的核心实现 - rm-datasource
关系型数据库RM的核心实现(Mysql) - tm
TM的核心实现 - spring、dubbo
针对Spring和dubbo项目的接入适配层
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的层次和责任划分,稍加整理,如下图:
官方提供的流程图,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.DefaultCore
+com.alibaba.fescar.server.coordinator.DefaultCoordinator
DefaultCore
实现了TransactionManager
和ResourceManagerOutbound
DefaultCoordinator
实现了ResourceManagerInbound
作为分布式系统,TM、RM和TC需要协作完成整个分布式事务的管控,自然是涉及到网络通信,Fescar基于Netty实现了系统间的交互。
下一篇我们先单独看看这部分的实现。Fescar源码阅读-RPC和消息