DefaultCoordinator1:seata Server分析(TC源码分析)
在seata tc服务的启动的时候都是通过它提供的启动脚本来启动,对于seata Server的入口分析,也是启动脚本就可以看出。如下我截最后执行命令,才下面可以很清晰的看到它的入口启动main类为io.seata.server.Server
exec "$JAVACMD" $JAVA_OPTS -server -Xmx2048m -Xms2048m -Xmn1024m -Xss512k -XX:SurvivorRatio=10 -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m -XX:MaxDirectMemorySize=1024m -XX:-OmitStackTraceInFastThrow -XX:-UseAdaptiveSizePolicy -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath="$BASEDIR"/logs/java_heapdump.hprof -XX:+DisableExplicitGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=75 -Xloggc:"$BASEDIR"/logs/seata_gc.log -verbose:gc -Dio.netty.leakDetectionLevel=advanced \
-classpath "$CLASSPATH" \
-Dapp.name="seata-server" \
-Dapp.pid="$$" \
-Dapp.repo="$REPO" \
-Dapp.home="$BASEDIR" \
-Dbasedir="$BASEDIR" \
io.seata.server.Server \
"$@"
1.1:Server
seata TC是一个很简单的由netty提供的server服务,经典的多reactor模式使得server端的性能既有,可以承受TM与RM端频繁的交互。
public class Server {
//最小pool执行线程数
private static final int MIN_SERVER_POOL_SIZE = 50;
//最大执行线程数
private static final int MAX_SERVER_POOL_SIZE = 500;
//请求等待队列最大值
private static final int MAX_TASK_QUEUE_SIZE = 20000;
//线程keep-alive 时间 500ms
private static final int KEEP_ALIVE_TIME = 500;
//worker 线程pool channel接受数据后由worker中线程处理执行
private static final ThreadPoolExecutor WORKING_THREADS = new ThreadPoolExecutor(MIN_SERVER_POOL_SIZE,
MAX_SERVER_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(MAX_TASK_QUEUE_SIZE),
new NamedThreadFactory("ServerHandlerThread", MAX_SERVER_POOL_SIZE), new ThreadPoolExecutor.CallerRunsPolicy());
/**
* The entry point of application.
*
* @param args the input arguments
* @throws IOException the io exception
*/
public static void main(String[] args) throws IOException {
// get port first, use to logback.xml
//获取启动端口
int port = PortHelper.getPort(args);
//将配置设置到环境中
System.setProperty(ConfigurationKeys.SERVER_PORT, Integer.toString(port));
// 创建log log使用logback管理
final Logger logger = LoggerFactory.getLogger(Server.class);
if (ContainerHelper.isRunningInContainer()) {
logger.info("The server is running in container.");
}
//initialize the parameter parser
//Note that the parameter parser should always be the first line to execute.
//Because, here we need to parse the parameters needed for startup.
//初始化请求参数解析器 将请求参数转化对象
ParameterParser parameterParser = new ParameterParser(args);
//初始化 metrics
MetricsManager.get().init();
//设置store.mode 类型 事务会话信息存储方式 目前支持3种 file本地文件(不支持HA),db数据库|redis(支持HA)
System.setProperty(ConfigurationKeys.STORE_MODE, parameterParser.getStoreMode());
//初始化NettyRemotingServer
NettyRemotingServer nettyRemotingServer = new NettyRemotingServer(WORKING_THREADS);
//设置 netty server监听port
nettyRemotingServer.setListenPort(parameterParser.getPort());
//初始化id发号器 用于tc生成的id 经典的雪花算法 在TC HA部署注意雪花算法问题
UUIDGenerator.init(parameterParser.getServerNode());
//log store mode : file, db, redis
//初始化 store
SessionHolder.init(parameterParser.getStoreMode());
DefaultCoordinator coordinator = new DefaultCoordinator(nettyRemotingServer);
coordinator.init();
//设置netty 输入in handler
nettyRemotingServer.setHandler(coordinator);
// 注册关闭钩子函数 关闭服务资源
ShutdownHook.getInstance().addDisposable(coordinator);
ShutdownHook.getInstance().addDisposable(nettyRemotingServer);
//验证host有效性 127.0.0.1 and 0.0.0.0 这里无效
//设置XID
if (NetUtil.isValidIp(parameterParser.getHost(), false)) {
XID.setIpAddress(parameterParser.getHost());
} else {
//获取实际地址
XID.setIpAddress(NetUtil.getLocalIp());
}
//设置端口号
XID.setPort(nettyRemotingServer.getListenPort());
try {
//初始化启动
nettyRemotingServer.init();
} catch (Throwable e) {
logger.error("nettyServer init error:{}", e.getMessage(), e);
System.exit(-1);
}
System.exit(0);
}
}
1.1:NettyRemotingServer
与之前描述的RmNettyRemotingClient与TmNettyRemotingClient类似(底层都是继承AbstractNettyRemoting抽象类),主要负责注册processor与destroyChannel,如下所示:
public class NettyRemotingServer extends AbstractNettyRemotingServer {
private static final Logger LOGGER = LoggerFactory.getLogger(NettyRemotingServer.class);
private TransactionMessageHandler transactionMessageHandler;
private final AtomicBoolean initialized = new AtomicBoolean(false);
@Override
public void init() {
// registry processor
registerProcessor();
if (initialized.compareAndSet(false, true)) {
//初始化server
super.init();
}
}
/**
* Instantiates a new Rpc remoting server.
*
* @param messageExecutor the message executor
*/
public NettyRemotingServer(ThreadPoolExecutor messageExecutor) {
super(messageExecutor, new NettyServerConfig());
}
/**
* Sets transactionMessageHandler.
*
* @param transactionMessageHandler the transactionMessageHandler
*/
public void setHandler(TransactionMessageHandler transactionMessageHandler) {
this.transactionMessageHandler = transactionMessageHandler;
}
public TransactionMessageHandler getHandler() {
return transactionMessageHandler;
}
@Override
public void destroyChannel(String serverAddress, Channel channel) {
//destroy channel
if (LOGGER.isInfoEnabled()) {
LOGGER.info("will destroy channel:{},address:{}", channel, serverAddress);
}
//关闭channel
channel.disconnect();
channel.close();
}
private void registerProcessor() {
// 1. 注册请求消息处理器
ServerOnRequestProcessor onRequestProcessor =
new ServerOnRequestProcessor(this, getHandler());
super.registerProcessor(MessageType.TYPE_BRANCH_REGISTER, onRequestProcessor, messageExecutor);
super.registerProcessor(MessageType.TYPE_BRANCH_STATUS_REPORT, onRequestProcessor, messageExecutor);
super.registerProcessor(MessageType.TYPE_GLOBAL_BEGIN, onRequestProcessor, messageExecutor);
super.registerProcessor(MessageType.TYPE_GLOBAL_COMMIT, onRequestProcessor, messageExecutor);
super.registerProcessor(MessageType.TYPE_GLOBAL_LOCK_QUERY, onRequestProcessor, messageExecutor);
super.registerProcessor(MessageType.TYPE_GLOBAL_REPORT, onRequestProcessor, messageExecutor);
super.registerProcessor(MessageType.TYPE_GLOBAL_ROLLBACK, onRequestProcessor, messageExecutor);
super.registerProcessor(MessageType.TYPE_GLOBAL_STATUS, onRequestProcessor, messageExecutor);
super.registerProcessor(MessageType.TYPE_SEATA_MERGE, onRequestProcessor, messageExecutor);
// 2. 注册response消息处理器
ServerOnResponseProcessor onResponseProcessor =
new ServerOnResponseProcessor(getHandler(), getFutures());
super.registerProcessor(MessageType.TYPE_BRANCH_COMMIT_RESULT, onResponseProcessor, messageExecutor);
super.registerProcessor(MessageType.TYPE_BRANCH_ROLLBACK_RESULT, onResponseProcessor, messageExecutor);
// 3. registry rm message processor
RegRmProcessor regRmProcessor = new RegRmProcessor(this);
super.registerProcessor(MessageType.TYPE_REG_RM, regRmProcessor, messageExecutor);
// 4. registry tm message processor
RegTmProcessor regTmProcessor = new RegTmProcessor(this);
super.registerProcessor(MessageType.TYPE_REG_CLT, regTmProcessor, null);
// 5. registry heartbeat message processor
ServerHeartbeatProcessor heartbeatMessageProcessor = new ServerHeartbeatProcessor(this);
super.registerProcessor(MessageType.TYPE_HEARTBEAT_MSG, heartbeatMessageProcessor, null);
}
}
从上述代码可以看出TC需要与TM,TM进行交互,并处理对于的request请求和response请求,都是通过Proessor做到的。而关于respnse的发送底层和之前描述的seata client的单条发送一致,都是基于AbstractNettyRemoting类实现。seata client包含了meager message的过程而server并没有此response过程。
1.2:NettyServerBootstrap
负责server端netty server有关的设置与初始化
public class NettyServerBootstrap implements RemotingBootstrap {
private static final Logger LOGGER = LoggerFactory.getLogger(NettyServerBootstrap.class);
private final ServerBootstrap serverBootstrap = new ServerBootstrap();
private final EventLoopGroup eventLoopGroupWorker;
private final EventLoopGroup eventLoopGroupBoss;
private final NettyServerConfig nettyServerConfig;
//piplines handler
private ChannelHandler[] channelHandlers;
private int listenPort;
private final AtomicBoolean initialized = new AtomicBoolean(false);
public NettyServerBootstrap(NettyServerConfig nettyServerConfig) {
this.nettyServerConfig = nettyServerConfig;
//是否开启 io多路复用 epoll模式
if (NettyServerConfig.enableEpoll()) {
this.eventLoopGroupBoss = new EpollEventLoopGroup(nettyServerConfig.getBossThreadSize(),
new NamedThreadFactory(nettyServerConfig.getBossThreadPrefix(), nettyServerConfig.getBossThreadSize()));
this.eventLoopGroupWorker = new EpollEventLoopGroup(nettyServerConfig.getServerWorkerThreads(),
new NamedThreadFactory(nettyServerConfig.getWorkerThreadPrefix(),
nettyServerConfig.getServerWorkerThreads()));
} else {
this.eventLoopGroupBoss = new NioEventLoopGroup(nettyServerConfig.getBossThreadSize(),
new NamedThreadFactory(nettyServerConfig.getBossThreadPrefix(), nettyServerConfig.getBossThreadSize()));
this.eventLoopGroupWorker = new NioEventLoopGroup(nettyServerConfig.getServerWorkerThreads(),
new NamedThreadFactory(nettyServerConfig.getWorkerThreadPrefix(),
nettyServerConfig.getServerWorkerThreads()));
}
// init listenPort in constructor so that getListenPort() will always get the exact port
//设置 端口号 默认8091
setListenPort(nettyServerConfig.getDefaultListenPort());
}
/**
* Sets channel handlers.
*
* @param handlers the handlers
*/
protected void setChannelHandlers(final ChannelHandler... handlers) {
if (handlers != null) {
channelHandlers = handlers;
}
}
/**
* Add channel pipeline last.
*
* @param channel the channel
* @param handlers the handlers
*/
private void addChannelPipelineLast(Channel channel, ChannelHandler... handlers) {
if (channel != null && handlers != null) {
channel.pipeline().addLast(handlers);
}
}
/**
* Sets listen port.
*
* @param listenPort the listen port
*/
public void setListenPort(int listenPort) {
if (listenPort <= 0) {
throw new IllegalArgumentException("listen port: " + listenPort + " is invalid!");
}
this.listenPort = listenPort;
}
/**
* Gets listen port.
*
* @return the listen port
*/
public int getListenPort() {
return listenPort;
}
@Override
public void start() {
//netty server端设置 启动
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))
//pipeline 设置 channel
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new IdleStateHandler(nettyServerConfig.getChannelMaxReadIdleSeconds(), 0, 0))
.addLast(new ProtocolV1Decoder())
.addLast(new ProtocolV1Encoder());
if (channelHandlers != null) {
addChannelPipelineLast(ch, channelHandlers);
}
}
});
try {
//绑定端口 同步等待启动
ChannelFuture future = this.serverBootstrap.bind(listenPort).sync();
LOGGER.info("Server started, listen port: {}", listenPort);
//将当前ip端口注册到注册中心(支持的注册中心可参考RegistryType)中
RegistryFactory.getInstance().register(new InetSocketAddress(XID.getIpAddress(), XID.getPort()));
initialized.set(true);
//关闭future的channel
future.channel().closeFuture().sync();
} catch (Exception exx) {
throw new RuntimeException(exx);
}
}
@Override
public void shutdown() {
//关闭netty server 销毁一些资源
try {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Shutting server down. ");
}
if (initialized.get()) {
//向注册中心发起下线通知
RegistryFactory.getInstance().unregister(new InetSocketAddress(XID.getIpAddress(), XID.getPort()));
//关闭与注册中心连接
RegistryFactory.getInstance().close();
//关闭等待一段时间等待正在传输网络中数据完成
TimeUnit.SECONDS.sleep(nettyServerConfig.getServerShutdownWaitTime());
}
//关闭netty资源
this.eventLoopGroupBoss.shutdownGracefully();
this.eventLoopGroupWorker.shutdownGracefully();
} catch (Exception exx) {
LOGGER.error(exx.getMessage());
}
}
}
1.3:ServerHandler
netty server读写channel数据handler,对于read本质通过判定消息类型,找到具体的消息processor,执行对应的process函数
@ChannelHandler.Sharable
class ServerHandler extends ChannelDuplexHandler {
/**
* Channel red.
*
* @param ctx the ctx
* @param msg the msg
* @throws Exception the exception
*/
@Override
public void channelRead(final ChannelHandlerContext ctx, Object msg) throws Exception {
if (!(msg instanceof RpcMessage)) {
return;
}
//根据message类型获取处理器
processMessage(ctx, (RpcMessage) msg);
}
@Override
public void channelWritabilityChanged(ChannelHandlerContext ctx) {
synchronized (lock) {
if (ctx.channel().isWritable()) {
lock.notifyAll();
}
}
ctx.fireChannelWritabilityChanged();
}
/**
* 处理不活动的Channel.
*
* @param ctx the ctx
* @throws Exception the exception
*/
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
debugLog("inactive:" + ctx);
if (messageExecutor.isShutdown()) {
return;
}
handleDisconnect(ctx);
super.channelInactive(ctx);
}
private void handleDisconnect(ChannelHandlerContext ctx) {
final String ipAndPort = NetUtil.toStringAddress(ctx.channel().remoteAddress());
RpcContext rpcContext = ChannelManager.getContextFromIdentified(ctx.channel());
if (LOGGER.isInfoEnabled()) {
LOGGER.info(ipAndPort + " to server channel inactive.");
}
if (rpcContext != null && rpcContext.getClientRole() != null) {
rpcContext.release();
if (LOGGER.isInfoEnabled()) {
LOGGER.info("remove channel:" + ctx.channel() + "context:" + rpcContext);
}
} else {
if (LOGGER.isInfoEnabled()) {
LOGGER.info("remove unused channel:" + ctx.channel());
}
}
}
/**
* Exception caught.
*
* @param ctx the ctx
* @param cause the cause
* @throws Exception the exception
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
if (LOGGER.isInfoEnabled()) {
LOGGER.info("channel exx:" + cause.getMessage() + ",channel:" + ctx.channel());
}
ChannelManager.releaseRpcContext(ctx.channel());
super.exceptionCaught(ctx, cause);
}
/**
* User event triggered.
*
* @param ctx the ctx
* @param evt the evt
* @throws Exception the exception
*/
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
if (evt instanceof IdleStateEvent) {
debugLog("idle:" + evt);
IdleStateEvent idleStateEvent = (IdleStateEvent) evt;
if (idleStateEvent.state() == IdleState.READER_IDLE) {
if (LOGGER.isInfoEnabled()) {
LOGGER.info("channel:" + ctx.channel() + " read idle.");
}
handleDisconnect(ctx);
try {
closeChannelHandlerContext(ctx);
} catch (Exception e) {
LOGGER.error(e.getMessage());
}
}
}
}
@Override
public void close(ChannelHandlerContext ctx, ChannelPromise future) throws Exception {
if (LOGGER.isInfoEnabled()) {
LOGGER.info(ctx + " will closed");
}
super.close(ctx, future);
}
}
1.4:RegistryFactory与RegistryService
RegistryFactory为注册中心工厂类,通过该类可以根据设置的注册中心类型获取到具体的RegistryService接口的详细实现的实例(单例模式),RegistryService封装了对注册中心的统一操作,例如上下线,心跳检测,订阅与取消,获取服务列表等。
public interface RegistryService<T> {
/**
* 设置的vgroupMapping前缀
*/
String PREFIX_SERVICE_MAPPING = "vgroupMapping.";
/**
* The constant PREFIX_SERVICE_ROOT.
*/
String PREFIX_SERVICE_ROOT = "service";
/**
* The constant CONFIG_SPLIT_CHAR.
*/
String CONFIG_SPLIT_CHAR = ".";
Set<String> SERVICE_GROUP_NAME = new HashSet<>();
/**
* Register.
*
* @param address the address
* @throws Exception the exception
*/
void register(InetSocketAddress address) throws Exception;
/**
* Unregister.
*
* @param address the address
* @throws Exception the exception
*/
void unregister(InetSocketAddress address) throws Exception;
/**
* Subscribe.
*
* @param cluster the cluster
* @param listener the listener
* @throws Exception the exception
*/
void subscribe(String cluster, T listener) throws Exception;
/**
* Unsubscribe.
*
* @param cluster the cluster
* @param listener the listener
* @throws Exception the exception
*/
void unsubscribe(String cluster, T listener) throws Exception;
/**
* Lookup list.
*
* @param key the key
* @return the list
* @throws Exception the exception
*/
List<InetSocketAddress> lookup(String key) throws Exception;
/**
* Close.
* @throws Exception
*/
void close() throws Exception;
/**
* Get current service group name
*
* @param key service group
* @return the service group name
*/
default String getServiceGroup(String key) {
key = PREFIX_SERVICE_ROOT + CONFIG_SPLIT_CHAR + PREFIX_SERVICE_MAPPING + key;
if (!SERVICE_GROUP_NAME.contains(key)) {
ConfigurationCache.addConfigListener(key);
SERVICE_GROUP_NAME.add(key);
}
return ConfigurationFactory.getInstance().getConfig(key);
}
}
1.4:消息处理器(按照执行顺序来描述)
1.4.1:RegTmProcessor
该处理器用于处理TM的channel注册类型的消息,将channel写入server本地环境,并记录channel的version,成功返回success,失败记录其失败原因
public class RegTmProcessor implements RemotingProcessor {
private static final Logger LOGGER = LoggerFactory.getLogger(RegTmProcessor.class);
private RemotingServer remotingServer;
private RegisterCheckAuthHandler checkAuthHandler;
public RegTmProcessor(RemotingServer remotingServer) {
this.remotingServer = remotingServer;
this.checkAuthHandler = EnhancedServiceLoader.load(RegisterCheckAuthHandler.class);
}
@Override
public void process(ChannelHandlerContext ctx, RpcMessage rpcMessage) throws Exception {
onRegTmMessage(ctx, rpcMessage);
}
private void onRegTmMessage(ChannelHandlerContext ctx, RpcMessage rpcMessage) {
//request message
RegisterTMRequest message = (RegisterTMRequest) rpcMessage.getBody();
//获取请求ip 端口
String ipAndPort = NetUtil.toStringAddress(ctx.channel().remoteAddress());
//写入当前version版本
Version.putChannelVersion(ctx.channel(), message.getVersion());
boolean isSuccess = false;
String errorInfo = StringUtils.EMPTY;
try {
if (null == checkAuthHandler || checkAuthHandler.regTransactionManagerCheckAuth(message)) {
//注册TM(写入缓存) channel后续处理使用
ChannelManager.registerTMChannel(message, ctx.channel());
Version.putChannelVersion(ctx.channel(), message.getVersion());
//成功标示
isSuccess = true;
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("checkAuth for client:{},vgroup:{},applicationId:{}",
ipAndPort, message.getTransactionServiceGroup(), message.getApplicationId());
}
}
} catch (Exception exx) {
isSuccess = false;
//保持记录errorinfo
errorInfo = exx.getMessage();
LOGGER.error("TM register fail, error message:{}", errorInfo);
}
//封装response消息
RegisterTMResponse response = new RegisterTMResponse(isSuccess);
if (StringUtils.isNotEmpty(errorInfo)) {
//error info
response.setMsg(errorInfo);
}
//异步发送response
remotingServer.sendAsyncResponse(rpcMessage, ctx.channel(), response);
if (LOGGER.isInfoEnabled()) {
LOGGER.info("TM register success,message:{},channel:{},client version:{}", message, ctx.channel(),
message.getVersion());
}
}
}
1.4.2:RegRmProcessor
该处理器用于处理RM的channel注册类型的消息,将channel写入server本地环境,并记录channel的version,成功返回success,失败记录其失败原因。该类与RegTmProcessor基本一直,这里不详细描述
1.4.3:ServerOnRequestProcessor
当channel注册完成后,剩下就是就是处理client端的请求的request数据,message类型的如下所示:

/**
* 处理 RM/TM 客户端 请求消息.
* <p>
* message type:
* RM:
* 1) {@link MergedWarpMessage}
* 2) {@link BranchRegisterRequest}
* 3) {@link BranchReportRequest}
* 4) {@link GlobalLockQueryRequest}
* TM:
* 1) {@link MergedWarpMessage}
* 2) {@link GlobalBeginRequest}
* 3) {@link GlobalCommitRequest}
* 4) {@link GlobalReportRequest}
* 5) {@link GlobalRollbackRequest}
* 6) {@link GlobalStatusRequest}
*
* @author zhangchenghui.dev@gmail.com
* @since 1.3.0
*/
public class ServerOnRequestProcessor implements RemotingProcessor {
private static final Logger LOGGER = LoggerFactory.getLogger(ServerOnRequestProcessor.class);
//实现 NettyRemotingServer
private RemotingServer remotingServer;
//实现 DefaultCoordinator
private TransactionMessageHandler transactionMessageHandler;
public ServerOnRequestProcessor(RemotingServer remotingServer, TransactionMessageHandler transactionMessageHandler) {
this.remotingServer = remotingServer;
this.transactionMessageHandler = transactionMessageHandler;
}
@Override
public void process(ChannelHandlerContext ctx, RpcMessage rpcMessage) throws Exception {
//验证当前请求channel是否在server注册成功
if (ChannelManager.isRegistered(ctx.channel())) {
//处理请求
onRequestMessage(ctx, rpcMessage);
} else {
try {
if (LOGGER.isInfoEnabled()) {
LOGGER.info("closeChannelHandlerContext channel:" + ctx.channel());
}
//无效channel 关闭
ctx.disconnect();
ctx.close();
} catch (Exception exx) {
LOGGER.error(exx.getMessage());
}
if (LOGGER.isInfoEnabled()) {
LOGGER.info(String.format("close a unhandled connection! [%s]", ctx.channel().toString()));
}
}
}
private void onRequestMessage(ChannelHandlerContext ctx, RpcMessage rpcMessage) {
//获取请求数据
Object message = rpcMessage.getBody();
//从ChannelManager缓存获取对应RpcContext
RpcContext rpcContext = ChannelManager.getContextFromIdentified(ctx.channel());
//记录日志
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("server received:{},clientIp:{},vgroup:{}", message,
NetUtil.toIpAddress(ctx.channel().remoteAddress()), rpcContext.getTransactionServiceGroup());
} else {
try {
BatchLogHandler.INSTANCE.getLogQueue()
.put(message + ",clientIp:" + NetUtil.toIpAddress(ctx.channel().remoteAddress()) + ",vgroup:"
+ rpcContext.getTransactionServiceGroup());
} catch (InterruptedException e) {
LOGGER.error("put message to logQueue error: {}", e.getMessage(), e);
}
}
//message 类型校验
if (!(message instanceof AbstractMessage)) {
return;
}
//如果是merged类型
if (message instanceof MergedWarpMessage) {
//定义结果集
AbstractResultMessage[] results = new AbstractResultMessage[((MergedWarpMessage) message).msgs.size()];
for (int i = 0; i < results.length; i++) {
final AbstractMessage subMessage = ((MergedWarpMessage) message).msgs.get(i);
//根据message 执行具体的TC业务逻辑
results[i] = transactionMessageHandler.onRequest(subMessage, rpcContext);
}
//多条result聚合发送
MergeResultMessage resultMessage = new MergeResultMessage();
resultMessage.setMsgs(results);
remotingServer.sendAsyncResponse(rpcMessage, ctx.channel(), resultMessage);
} else {
//单message request请求发送
final AbstractMessage msg = (AbstractMessage) message;
//根据message 执行具体的TC业务逻辑 返回结果
AbstractResultMessage result = transactionMessageHandler.onRequest(msg, rpcContext);
remotingServer.sendAsyncResponse(rpcMessage, ctx.channel(), result);
}
}
}
从上述源码可以看出TransactionMessageHandler(默认实DefaultCoordinato)负责处理关于TC中事务流程,对于TransactionMessageHandler的初始化在Server中构建。
1.4.4DefaultCoordinator(默认的协调者)
从该类的命令可以看出该类是作为TC的事务核心,协调TM,RM与TCserver之间关系。管理了多个定时调度器,用于handleRetryRollbacking(),handleRetryCommitting (),handleAsyncCommitting(),timeoutcheck(),undoLogDelete() 等任务。
public class DefaultCoordinator extends AbstractTCInboundHandler implements TransactionMessageHandler, Disposable {
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultCoordinator.class);
//定时任务关机最大等待时间 默认5s
private static final int TIMED_TASK_SHUTDOWN_MAX_WAIT_MILLS = 5000;
/**
* 提交重试周期 默认1s
*/
protected static final long COMMITTING_RETRY_PERIOD = CONFIG.getLong(ConfigurationKeys.COMMITING_RETRY_PERIOD,
1000L);
/**
* 异步提交重试周期 默认1s
*/
protected static final long ASYNC_COMMITTING_RETRY_PERIOD = CONFIG.getLong(
ConfigurationKeys.ASYN_COMMITING_RETRY_PERIOD, 1000L);
/**
* 回滚重试周期 默认1s
*/
protected static final long ROLLBACKING_RETRY_PERIOD = CONFIG.getLong(ConfigurationKeys.ROLLBACKING_RETRY_PERIOD,
1000L);
/**
* 超时重试周期 默认1s
*/
protected static final long TIMEOUT_RETRY_PERIOD = CONFIG.getLong(ConfigurationKeys.TIMEOUT_RETRY_PERIOD, 1000L);
/**
*
*/
protected static final long UNDO_LOG_DELETE_PERIOD = CONFIG.getLong(
ConfigurationKeys.TRANSACTION_UNDO_LOG_DELETE_PERIOD, 24 * 60 * 60 * 1000);
/**
*
* 事务 undo log 延迟删除周期 默认3min
*/
protected static final long UNDO_LOG_DELAY_DELETE_PERIOD = 3 * 60 * 1000;
private static final int ALWAYS_RETRY_BOUNDARY = 0;
//最大重试commit超时时间
private static final Duration MAX_COMMIT_RETRY_TIMEOUT = ConfigurationFactory.getInstance().getDuration(
ConfigurationKeys.MAX_COMMIT_RETRY_TIMEOUT, DurationUtil.DEFAULT_DURATION, 100);
//最大重试rollback超时时间
private static final Duration MAX_ROLLBACK_RETRY_TIMEOUT = ConfigurationFactory.getInstance().getDuration(
ConfigurationKeys.MAX_ROLLBACK_RETRY_TIMEOUT, DurationUtil.DEFAULT_DURATION, 100);
//开启
private static final boolean ROLLBACK_RETRY_TIMEOUT_UNLOCK_ENABLE = ConfigurationFactory.getInstance().getBoolean(
ConfigurationKeys.ROLLBACK_RETRY_TIMEOUT_UNLOCK_ENABLE, false);
/*定义server端重试线程pool*/
//rollback 重试
private ScheduledThreadPoolExecutor retryRollbacking = new ScheduledThreadPoolExecutor(1,
new NamedThreadFactory("RetryRollbacking", 1));
//commit重试
private ScheduledThreadPoolExecutor retryCommitting = new ScheduledThreadPoolExecutor(1,
new NamedThreadFactory("RetryCommitting", 1));
//异步提交
private ScheduledThreadPoolExecutor asyncCommitting = new ScheduledThreadPoolExecutor(1,
new NamedThreadFactory("AsyncCommitting", 1));
//tx超时检测
private ScheduledThreadPoolExecutor timeoutCheck = new ScheduledThreadPoolExecutor(1,
new NamedThreadFactory("TxTimeoutCheck", 1));
//undolog 日志生产任务
private ScheduledThreadPoolExecutor undoLogDelete = new ScheduledThreadPoolExecutor(1,
new NamedThreadFactory("UndoLogDelete", 1));
private RemotingServer remotingServer;
//全局事务执行有关底层核心类
private DefaultCore core;
private EventBus eventBus = EventBusManager.get();
/**
* Instantiates a new Default coordinator.
*
* @param remotingServer the remoting server
*/
public DefaultCoordinator(RemotingServer remotingServer) {
this.remotingServer = remotingServer;
this.core = new DefaultCore(remotingServer);
}
@Override
protected void doGlobalBegin(GlobalBeginRequest request, GlobalBeginResponse response, RpcContext rpcContext)
throws TransactionException {
//写response入xid
response.setXid(core.begin(rpcContext.getApplicationId(), rpcContext.getTransactionServiceGroup(),
request.getTransactionName(), request.getTimeout()));
if (LOGGER.isInfoEnabled()) {
LOGGER.info("Begin new global transaction applicationId: {},transactionServiceGroup: {}, transactionName: {},timeout:{},xid:{}",
rpcContext.getApplicationId(), rpcContext.getTransactionServiceGroup(), request.getTransactionName(), request.getTimeout(), response.getXid());
}
}
@Override
protected void doGlobalCommit(GlobalCommitRequest request, GlobalCommitResponse response, RpcContext rpcContext)
throws TransactionException {
//写入执行后全局状态
response.setGlobalStatus(core.commit(request.getXid()));
}
@Override
protected void doGlobalRollback(GlobalRollbackRequest request, GlobalRollbackResponse response,
RpcContext rpcContext) throws TransactionException {
//写入执行后全局状态
response.setGlobalStatus(core.rollback(request.getXid()));
}
@Override
protected void doGlobalStatus(GlobalStatusRequest request, GlobalStatusResponse response, RpcContext rpcContext)
throws TransactionException {
//获取xid对应全局事务状态
response.setGlobalStatus(core.getStatus(request.getXid()));
}
@Override
protected void doGlobalReport(GlobalReportRequest request, GlobalReportResponse response, RpcContext rpcContext)
throws TransactionException {
response.setGlobalStatus(core.globalReport(request.getXid(), request.getGlobalStatus()));
}
@Override
protected void doBranchRegister(BranchRegisterRequest request, BranchRegisterResponse response,
RpcContext rpcContext) throws TransactionException {
response.setBranchId(
core.branchRegister(request.getBranchType(), request.getResourceId(), rpcContext.getClientId(),
request.getXid(), request.getApplicationData(), request.getLockKey()));
}
@Override
protected void doBranchReport(BranchReportRequest request, BranchReportResponse response, RpcContext rpcContext)
throws TransactionException {
core.branchReport(request.getBranchType(), request.getXid(), request.getBranchId(), request.getStatus(),
request.getApplicationData());
}
@Override
protected void doLockCheck(GlobalLockQueryRequest request, GlobalLockQueryResponse response, RpcContext rpcContext)
throws TransactionException {
response.setLockable(
core.lockQuery(request.getBranchType(), request.getResourceId(), request.getXid(), request.getLockKey()));
}
/**
* Timeout check.
*
* @throws TransactionException the transaction exception
*/
protected void timeoutCheck() throws TransactionException {
Collection<GlobalSession> allSessions = SessionHolder.getRootSessionManager().allSessions();
if (CollectionUtils.isEmpty(allSessions)) {
return;
}
if (allSessions.size() > 0 && LOGGER.isDebugEnabled()) {
LOGGER.debug("Global transaction timeout check begin, size: {}", allSessions.size());
}
for (GlobalSession globalSession : allSessions) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(
globalSession.getXid() + " " + globalSession.getStatus() + " " + globalSession.getBeginTime() + " "
+ globalSession.getTimeout());
}
boolean shouldTimeout = SessionHolder.lockAndExecute(globalSession, () -> {
if (globalSession.getStatus() != GlobalStatus.Begin || !globalSession.isTimeout()) {
return false;
}
globalSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
globalSession.close();
globalSession.changeStatus(GlobalStatus.TimeoutRollbacking);
// transaction timeout and start rollbacking event
eventBus.post(
new GlobalTransactionEvent(globalSession.getTransactionId(), GlobalTransactionEvent.ROLE_TC,
globalSession.getTransactionName(), globalSession.getBeginTime(), null,
globalSession.getStatus()));
return true;
});
if (!shouldTimeout) {
continue;
}
LOGGER.info("Global transaction[{}] is timeout and will be rollback.", globalSession.getXid());
globalSession.addSessionLifecycleListener(SessionHolder.getRetryRollbackingSessionManager());
SessionHolder.getRetryRollbackingSessionManager().addGlobalSession(globalSession);
}
if (allSessions.size() > 0 && LOGGER.isDebugEnabled()) {
LOGGER.debug("Global transaction timeout check end. ");
}
}
/**
* Handle retry rollbacking.
*/
protected void handleRetryRollbacking() {
//获取当前为Rollbacking的session
Collection<GlobalSession> rollbackingSessions = SessionHolder.getRetryRollbackingSessionManager().allSessions();
if (CollectionUtils.isEmpty(rollbackingSessions)) {
return;
}
long now = System.currentTimeMillis();
for (GlobalSession rollbackingSession : rollbackingSessions) {
try {
//验证当前全局事务状态是否为rollback
if (rollbackingSession.getStatus().equals(GlobalStatus.Rollbacking) && !rollbackingSession.isRollbackingDead()) {
continue;
}
//判断是否超时 若超时关闭该session
//防止重复回滚
if (isRetryTimeout(now, MAX_ROLLBACK_RETRY_TIMEOUT.toMillis(), rollbackingSession.getBeginTime())) {
if (ROLLBACK_RETRY_TIMEOUT_UNLOCK_ENABLE) {
rollbackingSession.clean();
}
/**
* 防止线程安全问题
*/
SessionHolder.getRetryRollbackingSessionManager().removeGlobalSession(rollbackingSession);
LOGGER.info("Global transaction rollback retry timeout and has removed [{}]", rollbackingSession.getXid());
continue;
}
rollbackingSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
//执行全局回滚
core.doGlobalRollback(rollbackingSession, true);
} catch (TransactionException ex) {
LOGGER.info("Failed to retry rollbacking [{}] {} {}", rollbackingSession.getXid(), ex.getCode(), ex.getMessage());
}
}
}
/**
* Handle retry committing.
*/
protected void handleRetryCommitting() {
Collection<GlobalSession> committingSessions = SessionHolder.getRetryCommittingSessionManager().allSessions();
if (CollectionUtils.isEmpty(committingSessions)) {
return;
}
long now = System.currentTimeMillis();
for (GlobalSession committingSession : committingSessions) {
try {
//验证是否
if (isRetryTimeout(now, MAX_COMMIT_RETRY_TIMEOUT.toMillis(), committingSession.getBeginTime())) {
/**
* Prevent thread safety issues
*/
SessionHolder.getRetryCommittingSessionManager().removeGlobalSession(committingSession);
LOGGER.error("Global transaction commit retry timeout and has removed [{}]", committingSession.getXid());
continue;
}
committingSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
//执行全局事务commit
core.doGlobalCommit(committingSession, true);
} catch (TransactionException ex) {
LOGGER.info("Failed to retry committing [{}] {} {}", committingSession.getXid(), ex.getCode(), ex.getMessage());
}
}
}
private boolean isRetryTimeout(long now, long timeout, long beginTime) {
return timeout >= ALWAYS_RETRY_BOUNDARY && now - beginTime > timeout;
}
/**
* Handle async committing.
*/
protected void handleAsyncCommitting() {
Collection<GlobalSession> asyncCommittingSessions = SessionHolder.getAsyncCommittingSessionManager()
.allSessions();
if (CollectionUtils.isEmpty(asyncCommittingSessions)) {
return;
}
for (GlobalSession asyncCommittingSession : asyncCommittingSessions) {
try {
// Instruction reordering in DefaultCore#asyncCommit may cause this situation
if (GlobalStatus.AsyncCommitting != asyncCommittingSession.getStatus()) {
continue;
}
asyncCommittingSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
core.doGlobalCommit(asyncCommittingSession, true);
} catch (TransactionException ex) {
LOGGER.error("Failed to async committing [{}] {} {}", asyncCommittingSession.getXid(), ex.getCode(), ex.getMessage(), ex);
}
}
}
/**
* Undo log delete.
*/
protected void undoLogDelete() {
//获取当前有效rm
Map<String, Channel> rmChannels = ChannelManager.getRmChannels();
if (rmChannels == null || rmChannels.isEmpty()) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("no active rm channels to delete undo log");
}
return;
}
//undolog 最大存储时间 默认7天
short saveDays = CONFIG.getShort(ConfigurationKeys.TRANSACTION_UNDO_LOG_SAVE_DAYS,
UndoLogDeleteRequest.DEFAULT_SAVE_DAYS);
for (Map.Entry<String, Channel> channelEntry : rmChannels.entrySet()) {
String resourceId = channelEntry.getKey();
//发送到各RM端删除undolog请求
UndoLogDeleteRequest deleteRequest = new UndoLogDeleteRequest();
deleteRequest.setResourceId(resourceId);
deleteRequest.setSaveDays(saveDays > 0 ? saveDays : UndoLogDeleteRequest.DEFAULT_SAVE_DAYS);
try {
//发起删除undolog请求
remotingServer.sendAsyncRequest(channelEntry.getValue(), deleteRequest);
} catch (Exception e) {
LOGGER.error("Failed to async delete undo log resourceId = {}, exception: {}", resourceId, e.getMessage());
}
}
}
/**
* Init.
*/
public void init() {
//初始化定时任务
retryRollbacking.scheduleAtFixedRate(() -> {
try {
handleRetryRollbacking();
} catch (Exception e) {
LOGGER.info("Exception retry rollbacking ... ", e);
}
}, 0, ROLLBACKING_RETRY_PERIOD, TimeUnit.MILLISECONDS);
retryCommitting.scheduleAtFixedRate(() -> {
try {
handleRetryCommitting();
} catch (Exception e) {
LOGGER.info("Exception retry committing ... ", e);
}
}, 0, COMMITTING_RETRY_PERIOD, TimeUnit.MILLISECONDS);
asyncCommitting.scheduleAtFixedRate(() -> {
try {
handleAsyncCommitting();
} catch (Exception e) {
LOGGER.info("Exception async committing ... ", e);
}
}, 0, ASYNC_COMMITTING_RETRY_PERIOD, TimeUnit.MILLISECONDS);
timeoutCheck.scheduleAtFixedRate(() -> {
try {
timeoutCheck();
} catch (Exception e) {
LOGGER.info("Exception timeout checking ... ", e);
}
}, 0, TIMEOUT_RETRY_PERIOD, TimeUnit.MILLISECONDS);
undoLogDelete.scheduleAtFixedRate(() -> {
try {
undoLogDelete();
} catch (Exception e) {
LOGGER.info("Exception undoLog deleting ... ", e);
}
}, UNDO_LOG_DELAY_DELETE_PERIOD, UNDO_LOG_DELETE_PERIOD, TimeUnit.MILLISECONDS);
}
@Override
public AbstractResultMessage onRequest(AbstractMessage request, RpcContext context) {
if (!(request instanceof AbstractTransactionRequestToTC)) {
throw new IllegalArgumentException();
}
AbstractTransactionRequestToTC transactionRequest = (AbstractTransactionRequestToTC) request;
transactionRequest.setTCInboundHandler(this);
//
return transactionRequest.handle(context);
}
@Override
public void onResponse(AbstractResultMessage response, RpcContext context) {
if (!(response instanceof AbstractTransactionResponse)) {
throw new IllegalArgumentException();
}
}
@Override
public void destroy() {
// 1. 关闭定时任务
retryRollbacking.shutdown();
retryCommitting.shutdown();
asyncCommitting.shutdown();
timeoutCheck.shutdown();
try {
//等待超时时间内执行完成
retryRollbacking.awaitTermination(TIMED_TASK_SHUTDOWN_MAX_WAIT_MILLS, TimeUnit.MILLISECONDS);
retryCommitting.awaitTermination(TIMED_TASK_SHUTDOWN_MAX_WAIT_MILLS, TimeUnit.MILLISECONDS);
asyncCommitting.awaitTermination(TIMED_TASK_SHUTDOWN_MAX_WAIT_MILLS, TimeUnit.MILLISECONDS);
timeoutCheck.awaitTermination(TIMED_TASK_SHUTDOWN_MAX_WAIT_MILLS, TimeUnit.MILLISECONDS);
} catch (InterruptedException ignore) {
}
// 2. 关闭netty服务
if (remotingServer instanceof NettyRemotingServer) {
((NettyRemotingServer) remotingServer).destroy();
}
// 3. last destroy SessionHolder
SessionHolder.destroy();
}
}
AbstractTCInboundHandler:DefaultCoordinator实现的分类,通过模版方法模式封装各分布式阶段执行流程,只对外提供具体的核心方法抽象类。为以后的扩展提供基础。
public abstract class AbstractTCInboundHandler extends AbstractExceptionHandler implements TCInboundHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractTCInboundHandler.class);
/**
* 该抽象类定义了分布式事务TC阶段所有抽象方法
* 针对每一个阶段根据请求request不同提供不同的handle处理 这里使用了模版方法模式 最终调用实现类中具体方法方法
*/
@Override
public GlobalBeginResponse handle(GlobalBeginRequest request, final RpcContext rpcContext) {
GlobalBeginResponse response = new GlobalBeginResponse();
//执行具体阶段请求
exceptionHandleTemplate(new AbstractCallback<GlobalBeginRequest, GlobalBeginResponse>() {
@Override
public void execute(GlobalBeginRequest request, GlobalBeginResponse response) throws TransactionException {
try {
doGlobalBegin(request, response, rpcContext);
} catch (StoreException e) {
throw new TransactionException(TransactionExceptionCode.FailedStore,
String.format("begin global request failed. xid=%s, msg=%s", response.getXid(), e.getMessage()),
e);
}
}
}, request, response);
return response;
}
/**
* Do global begin.
*
* @param request the request
* @param response the response
* @param rpcContext the rpc context
* @throws TransactionException the transaction exception
*/
protected abstract void doGlobalBegin(GlobalBeginRequest request, GlobalBeginResponse response,
RpcContext rpcContext) throws TransactionException;
@Override
public GlobalCommitResponse handle(GlobalCommitRequest request, final RpcContext rpcContext) {
GlobalCommitResponse response = new GlobalCommitResponse();
//设置response状态为commiting
response.setGlobalStatus(GlobalStatus.Committing);
exceptionHandleTemplate(new AbstractCallback<GlobalCommitRequest, GlobalCommitResponse>() {
@Override
public void execute(GlobalCommitRequest request, GlobalCommitResponse response)
throws TransactionException {
try {
doGlobalCommit(request, response, rpcContext);
} catch (StoreException e) {
throw new TransactionException(TransactionExceptionCode.FailedStore,
String.format("global commit request failed. xid=%s, msg=%s", request.getXid(), e.getMessage()),
e);
}
}
//异常处理 由统一异常处理类AbstractExceptionHandler处理
@Override
public void onTransactionException(GlobalCommitRequest request, GlobalCommitResponse response,
TransactionException tex) {
super.onTransactionException(request, response, tex);
checkTransactionStatus(request, response);
}
@Override
public void onException(GlobalCommitRequest request, GlobalCommitResponse response, Exception rex) {
super.onException(request, response, rex);
checkTransactionStatus(request, response);
}
}, request, response);
return response;
}
/**
* Do global commit.
*
* @param request the request
* @param response the response
* @param rpcContext the rpc context
* @throws TransactionException the transaction exception
*/
protected abstract void doGlobalCommit(GlobalCommitRequest request, GlobalCommitResponse response,
RpcContext rpcContext) throws TransactionException;
@Override
public GlobalRollbackResponse handle(GlobalRollbackRequest request, final RpcContext rpcContext) {
GlobalRollbackResponse response = new GlobalRollbackResponse();
response.setGlobalStatus(GlobalStatus.Rollbacking);
exceptionHandleTemplate(new AbstractCallback<GlobalRollbackRequest, GlobalRollbackResponse>() {
@Override
public void execute(GlobalRollbackRequest request, GlobalRollbackResponse response)
throws TransactionException {
try {
doGlobalRollback(request, response, rpcContext);
} catch (StoreException e) {
throw new TransactionException(TransactionExceptionCode.FailedStore, String
.format("global rollback request failed. xid=%s, msg=%s", request.getXid(), e.getMessage()), e);
}
}
@Override
public void onTransactionException(GlobalRollbackRequest request, GlobalRollbackResponse response,
TransactionException tex) {
super.onTransactionException(request, response, tex);
// may be appears StoreException outer layer method catch
checkTransactionStatus(request, response);
}
@Override
public void onException(GlobalRollbackRequest request, GlobalRollbackResponse response, Exception rex) {
super.onException(request, response, rex);
// may be appears StoreException outer layer method catch
checkTransactionStatus(request, response);
}
}, request, response);
return response;
}
/**
* Do global rollback.
*
* @param request the request
* @param response the response
* @param rpcContext the rpc context
* @throws TransactionException the transaction exception
*/
protected abstract void doGlobalRollback(GlobalRollbackRequest request, GlobalRollbackResponse response,
RpcContext rpcContext) throws TransactionException;
@Override
public BranchRegisterResponse handle(BranchRegisterRequest request, final RpcContext rpcContext) {
BranchRegisterResponse response = new BranchRegisterResponse();
exceptionHandleTemplate(new AbstractCallback<BranchRegisterRequest, BranchRegisterResponse>() {
@Override
public void execute(BranchRegisterRequest request, BranchRegisterResponse response)
throws TransactionException {
try {
doBranchRegister(request, response, rpcContext);
} catch (StoreException e) {
throw new TransactionException(TransactionExceptionCode.FailedStore, String
.format("branch register request failed. xid=%s, msg=%s", request.getXid(), e.getMessage()), e);
}
}
}, request, response);
return response;
}
/**
* Do branch register.
*
* @param request the request
* @param response the response
* @param rpcContext the rpc context
* @throws TransactionException the transaction exception
*/
protected abstract void doBranchRegister(BranchRegisterRequest request, BranchRegisterResponse response,
RpcContext rpcContext) throws TransactionException;
@Override
public BranchReportResponse handle(BranchReportRequest request, final RpcContext rpcContext) {
BranchReportResponse response = new BranchReportResponse();
exceptionHandleTemplate(new AbstractCallback<BranchReportRequest, BranchReportResponse>() {
@Override
public void execute(BranchReportRequest request, BranchReportResponse response)
throws TransactionException {
try {
doBranchReport(request, response, rpcContext);
} catch (StoreException e) {
throw new TransactionException(TransactionExceptionCode.FailedStore, String
.format("branch report request failed. xid=%s, branchId=%s, msg=%s", request.getXid(),
request.getBranchId(), e.getMessage()), e);
}
}
}, request, response);
return response;
}
/**
* Do branch report.
*
* @param request the request
* @param rpcContext the rpc context
* @throws TransactionException the transaction exception
*/
protected abstract void doBranchReport(BranchReportRequest request, BranchReportResponse response,
RpcContext rpcContext) throws TransactionException;
@Override
public GlobalLockQueryResponse handle(GlobalLockQueryRequest request, final RpcContext rpcContext) {
GlobalLockQueryResponse response = new GlobalLockQueryResponse();
exceptionHandleTemplate(new AbstractCallback<GlobalLockQueryRequest, GlobalLockQueryResponse>() {
@Override
public void execute(GlobalLockQueryRequest request, GlobalLockQueryResponse response)
throws TransactionException {
try {
doLockCheck(request, response, rpcContext);
} catch (StoreException e) {
throw new TransactionException(TransactionExceptionCode.FailedStore, String
.format("global lock query request failed. xid=%s, msg=%s", request.getXid(), e.getMessage()),
e);
}
}
}, request, response);
return response;
}
/**
* Do lock check.
*
* @param request the request
* @param response the response
* @param rpcContext the rpc context
* @throws TransactionException the transaction exception
*/
protected abstract void doLockCheck(GlobalLockQueryRequest request, GlobalLockQueryResponse response,
RpcContext rpcContext) throws TransactionException;
@Override
public GlobalStatusResponse handle(GlobalStatusRequest request, final RpcContext rpcContext) {
GlobalStatusResponse response = new GlobalStatusResponse();
response.setGlobalStatus(GlobalStatus.UnKnown);
exceptionHandleTemplate(new AbstractCallback<GlobalStatusRequest, GlobalStatusResponse>() {
@Override
public void execute(GlobalStatusRequest request, GlobalStatusResponse response)
throws TransactionException {
try {
doGlobalStatus(request, response, rpcContext);
} catch (StoreException e) {
throw new TransactionException(TransactionExceptionCode.FailedStore,
String.format("global status request failed. xid=%s, msg=%s", request.getXid(), e.getMessage()),
e);
}
}
@Override
public void onTransactionException(GlobalStatusRequest request, GlobalStatusResponse response,
TransactionException tex) {
super.onTransactionException(request, response, tex);
checkTransactionStatus(request, response);
}
@Override
public void onException(GlobalStatusRequest request, GlobalStatusResponse response, Exception rex) {
super.onException(request, response, rex);
checkTransactionStatus(request, response);
}
}, request, response);
return response;
}
/**
* Do global status.
*
* @param request the request
* @param response the response
* @param rpcContext the rpc context
* @throws TransactionException the transaction exception
*/
protected abstract void doGlobalStatus(GlobalStatusRequest request, GlobalStatusResponse response,
RpcContext rpcContext) throws TransactionException;
@Override
public GlobalReportResponse handle(GlobalReportRequest request, final RpcContext rpcContext) {
GlobalReportResponse response = new GlobalReportResponse();
response.setGlobalStatus(request.getGlobalStatus());
exceptionHandleTemplate(new AbstractCallback<GlobalReportRequest, GlobalReportResponse>() {
@Override
public void execute(GlobalReportRequest request, GlobalReportResponse response)
throws TransactionException {
doGlobalReport(request, response, rpcContext);
}
}, request, response);
return response;
}
/**
* Do global report.
*
* @param request the request
* @param response the response
* @param rpcContext the rpc context
* @throws TransactionException the transaction exception
*/
protected abstract void doGlobalReport(GlobalReportRequest request, GlobalReportResponse response,
RpcContext rpcContext) throws TransactionException;
/**
* 检测当前分布式全局事务状态
* @param request
* @param response
*/
private void checkTransactionStatus(AbstractGlobalEndRequest request, AbstractGlobalEndResponse response) {
try {
//获取事务对应session对象
GlobalSession globalSession = SessionHolder.findGlobalSession(request.getXid(), false);
if (globalSession != null) {
response.setGlobalStatus(globalSession.getStatus());
} else {
//事务结束
response.setGlobalStatus(GlobalStatus.Finished);
}
} catch (Exception exx) {
LOGGER.error("check transaction status error,{}]", exx.getMessage());
}
}
}
统一异常handler类:AbstractExceptionHandler
内部定义执行回调接口Callback及其抽象类实现AbstractCallback,用于统一处理执行过程发生的异常并可正常response返回
public abstract class AbstractExceptionHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractExceptionHandler.class);
/**
* The constant CONFIG.
*/
protected static final Configuration CONFIG = ConfigurationFactory.getInstance();
/**
*定义事务执行流程回调函数
*
* @param <T> the type parameter
* @param <S> the type parameter
*/
public interface Callback<T extends AbstractTransactionRequest, S extends AbstractTransactionResponse> {
/**
* Execute.
*
* @param request the request
* @param response the response
* @throws TransactionException the transaction exception
*/
void execute(T request, S response) throws TransactionException;
/**
* on Success
*
* @param request
* @param response
*/
void onSuccess(T request, S response);
/**
* onTransactionException
*
* @param request
* @param response
* @param exception
*/
void onTransactionException(T request, S response, TransactionException exception);
/**
* on other exception
*
* @param request
* @param response
* @param exception
*/
void onException(T request, S response, Exception exception);
}
//AbstractCallback实现
public abstract static class AbstractCallback<T extends AbstractTransactionRequest, S extends AbstractTransactionResponse>
implements Callback<T, S> {
@Override
public void onSuccess(T request, S response) {
response.setResultCode(ResultCode.Success);
}
//发生异常时 对response统一处理
@Override
public void onTransactionException(T request, S response,
TransactionException tex) {
//返回状态failed
response.setTransactionExceptionCode(tex.getCode());
response.setResultCode(ResultCode.Failed);
response.setMsg("TransactionException[" + tex.getMessage() + "]");
}
@Override
public void onException(T request, S response, Exception rex) {
response.setResultCode(ResultCode.Failed);
response.setMsg("RuntimeException[" + rex.getMessage() + "]");
}
}
/**
* 执行过程中发生任何异常处理模版
*
* @param callback the callback
* @param request the request
* @param response the response
*/
public <T extends AbstractTransactionRequest, S extends AbstractTransactionResponse> void exceptionHandleTemplate(Callback<T, S> callback, T request, S response) {
try {
//回调执行
callback.execute(request, response);
callback.onSuccess(request, response);
} catch (TransactionException tex) {
LOGGER.error("Catch TransactionException while do RPC, request: {}", request, tex);
callback.onTransactionException(request, response, tex);
} catch (RuntimeException rex) {
LOGGER.error("Catch RuntimeException while do RPC, request: {}", request, rex);
//其它异常调用具体实现
callback.onException(request, response, rex);
}
}
}
1.4.5:DefaultCore(Core接口默认实现)
全局事务执行有关底层核心类,提供了以下核心方法

1.4.6:ServerHeartbeatProcessor
很简单的处理客户的心跳检测,对client做出正常响应即可
/**
* 处理客户端心跳消息请求(PING)
* <p>
* process message type:
* {@link HeartbeatMessage}
*
* @author zhangchenghui.dev@gmail.com
* @since 1.3.0
*/
public class ServerHeartbeatProcessor implements RemotingProcessor {
private static final Logger LOGGER = LoggerFactory.getLogger(ServerHeartbeatProcessor.class);
private RemotingServer remotingServer;
public ServerHeartbeatProcessor(RemotingServer remotingServer) {
this.remotingServer = remotingServer;
}
@Override
public void process(ChannelHandlerContext ctx, RpcMessage rpcMessage) throws Exception {
try {
remotingServer.sendAsyncResponse(rpcMessage, ctx.channel(), HeartbeatMessage.PONG);
} catch (Throwable throwable) {
LOGGER.error("send response error: {}", throwable.getMessage(), throwable);
}
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("received PING from {}", ctx.channel().remoteAddress());
}
}
}
详细参考如下流程图
4274



被折叠的 条评论
为什么被折叠?



