TC是什么
Transcation Coordinate(TC),分布式事务中协调者的角色,管理全局事务的状态信息,包括全部事务的开启、提交、回滚管理,分支事务的注册、提交、回滚、状态上报。
Seata的TC启动方式:
sh fescar-server.sh $LISTEN_PORT $PATH_FOR_PERSISTENT_DATA
e.g.
sh fescar-server.sh 8091 /home/admin/fescar/data/
接下来我们看下fescar-server.sh
中的内容,我们可以知道,最终会通过类com.alibaba.fescar.server.Server
来完成TC服务的启动。
...
exec "$JAVACMD" $JAVA_OPTS -server -XX:MaxDirectMemorySize=1024M \
-classpath "$CLASSPATH" \
-Dapp.name="fescar-server" \
-Dapp.pid="$$" \
-Dapp.repo="$REPO" \
-Dapp.home="$BASEDIR" \
-Dbasedir="$BASEDIR" \
io.seata.server.Server \
"$@"
Server的启动过程解析
io.seata.server.Server
RpcServer rpcServer = new RpcServer(WORKING_THREADS);
.....
//log store mode : file、db
String storeMode = null;
if (args.length > 1) {
storeMode = args[1];
}
SessionHolder.init(storeMode);
DefaultCoordinator coordinator = new DefaultCoordinator(rpcServer);
coordinator.init();
rpcServer.setHandler(new DefaultCoordinator(rpcServer));
UUIDGenerator.init(1);
if (args.length > 2) {
XID.setIpAddress(args[2]);
} else {
XID.setIpAddress(NetUtil.getLocalIp());
}
XID.setPort(rpcServer.getListenPort());
rpcServer.init();
System.exit(0);
- 进行SessionHolder的初始化,主要初始化一些SessionManager,用户后续的session的管理和持久化工作,当前的实现是DefaultSessionManager和FileBaseSessionManager。
- 初始化DefaultCoordinator,其实现了ChannelHandler接口,启动netty服务后,会作为channelHandler完成相关消息的读取处理,接下来我们会详细介绍。
- 初始化UUIDGenerator,启动唯一ID生成服务,目前采用AtomicLong来实现
- 启动Netty服务监听接口
netty服务的启动(AbstractRpcRemotingServer)
public void start() {
this.serverBootstrap.group(this.eventLoopGroupBoss, this.eventLoopGroupWorker)
.channel(nettyServerConfig.SERVER_CHANNEL_CLAZZ)
.option(ChannelOption.SO_BACKLOG, nettyServerConfig.getSoBackLogSize())
.option(ChannelOption.SO_REUSEADDR, true)
.childOption(ChannelOption.SO_KEEPALIVE, true)
.childOption(ChannelOption.TCP_NODELAY, true)
.childOption(ChannelOption.SO_SNDBUF, nettyServerConfig.getServerSocketSendBufSize())
.childOption(ChannelOption.SO_RCVBUF, nettyServerConfig.getServerSocketResvBufSize())
.childOption(ChannelOption.WRITE_BUFFER_WATER_MARK,
new WriteBufferWaterMark(nettyServerConfig.getWriteBufferLowWaterMark(),
nettyServerConfig.getWriteBufferHighWaterMark()))
.localAddress(new InetSocketAddress(listenPort))
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new IdleStateHandler(nettyServerConfig.getChannelMaxReadIdleSeconds(), 0, 0))
.addLast(new MessageCodecHandler());
if (null != channelHandlers) {
addChannelPipelineLast(ch, channelHandlers);
}
}
});
if (nettyServerConfig.isEnableServerPooledByteBufAllocator()) {
this.serverBootstrap.childOption(ChannelOption.ALLOCATOR, NettyServerConfig.DIRECT_BYTE_BUF_ALLOCATOR);
}
try {
ChannelFuture future = this.serverBootstrap.bind(listenPort).sync();
LOGGER.info("Server started ... ");
RegistryFactory.getInstance().register(new InetSocketAddress(XID.getIpAddress(), XID.getPort()));
initialized.set(true);
future.channel().closeFuture().sync();
} catch (Exception exx) {
throw new RuntimeException(exx);
}
}
TC能力开放接口
Transcation Coordinator的默认实现类是DefaultCoordinator
,我们可以查看其类的依赖关系图,其实现了接口类TCInboundHandler
,对外向TransactionManger提供了七大接口。
- 面向TM的全局事务开启接口
- 面向TM的全局事务提交接口
- 面向TM的全局事务回滚接口
- 面向TM的全局事务状态查询接口
- 面向TM的的锁定查询接口
- 面向RM的分支事务注册接口
- 面向RM的分支事务状态更新接口
ResourceManagerOutbound
: 向RM提供相关的分支事务接口
- 分支事务的注册
- 分支事务的状态上报
- 锁状态的查询
全局事务开启
这一章节我们介绍下TM调用TC开启事务的全流程交互消息图。
TM的事务开启通过DefaultTransactionManager.begin
方法来开启,其最终发通不过netty的channel将序列化后的数据发送到Server
端。
public String begin(String applicationId, String transactionServiceGroup, String name, int timeout)
throws TransactionException {
GlobalBeginRequest request = new GlobalBeginRequest();
request.setTransactionName(name);
request.setTimeout(timeout);
GlobalBeginResponse response = (GlobalBeginResponse)syncCall(request);
return response.getXid();
}
Netty Server接受到消息后会通过RpcServer.channelRead(final ChannelHandlerContext ctx, Object msg)
来进行处理,我们通过流程图来看下具体的调用链路关系图。
其它的代码代码也可以按照这个链路去查看,在此不在一一介绍
待完善的功能点
- TC本身的高可用
- RM本身的高可用,一个resourceId对应的RM异常后,可以通过相同resourceID其它的Rm来完成分支的提交和回滚
- LockManager锁机制的高可用、高性能和持久化
网友评论