下載Seata服務端源代碼
這樣用的是Seata的最新版本V1.0
解壓源代碼文件, 導入源代碼到IDEA當中
Seata服務端源代碼是一個標準的Maven工程,很容易很入到IDEA工具當中,最後源代碼工程文件目錄如下:
查看Seata的啓動腳本
#!/bin/sh
# resolve links - $0 may be a softlink
PRG="$0"
while [ -h "$PRG" ]; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`/"$link"
fi
done
PRGDIR=`dirname "$PRG"`
BASEDIR=`cd "$PRGDIR/.." >/dev/null; pwd`
# Reset the REPO variable. If you need to influence this use the environment setup file.
REPO=
# OS specific support. $var _must_ be set to either true or false.
cygwin=false;
darwin=false;
case "`uname`" in
CYGWIN*) cygwin=true ;;
Darwin*) darwin=true
if [ -z "$JAVA_VERSION" ] ; then
JAVA_VERSION="CurrentJDK"
else
echo "Using Java version: $JAVA_VERSION"
fi
if [ -z "$JAVA_HOME" ]; then
if [ -x "/usr/libexec/java_home" ]; then
JAVA_HOME=`/usr/libexec/java_home`
else
JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/${JAVA_VERSION}/Home
fi
fi
;;
esac
if [ -z "$JAVA_HOME" ] ; then
if [ -r /etc/gentoo-release ] ; then
JAVA_HOME=`java-config --jre-home`
fi
fi
# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
[ -n "$CLASSPATH" ] && CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
fi
# If a specific java binary isn't specified search for the standard 'java' binary
if [ -z "$JAVACMD" ] ; then
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
else
JAVACMD=`which java`
fi
fi
if [ ! -x "$JAVACMD" ] ; then
echo "Error: JAVA_HOME is not defined correctly." 1>&2
echo " We cannot execute $JAVACMD" 1>&2
exit 1
fi
if [ -z "$REPO" ]
then
REPO="$BASEDIR"/lib
fi
CLASSPATH="$BASEDIR"/conf:"$REPO"/*
ENDORSED_DIR=
if [ -n "$ENDORSED_DIR" ] ; then
CLASSPATH=$BASEDIR/$ENDORSED_DIR/*:$CLASSPATH
fi
if [ -n "$CLASSPATH_PREFIX" ] ; then
CLASSPATH=$CLASSPATH_PREFIX:$CLASSPATH
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
[ -n "$CLASSPATH" ] && CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
[ -n "$HOME" ] && HOME=`cygpath --path --windows "$HOME"`
[ -n "$BASEDIR" ] && BASEDIR=`cygpath --path --windows "$BASEDIR"`
[ -n "$REPO" ] && REPO=`cygpath --path --windows "$REPO"`
fi
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 \
"$@"
啓動腳本分析
從腳本當中可以看到啓動的類入口爲io.seata.server.Server,從源代碼當中可以明顯的看出Seata的底層通信框架使用的是Netty
Seata服務端啓動類
/**
* The type Server.
* 服務器端啓動
* @author slievrly
*/
public class Server {
private static final Logger LOGGER = LoggerFactory.getLogger(Server.class);
private static final int MIN_SERVER_POOL_SIZE = 100;
private static final int MAX_SERVER_POOL_SIZE = 500;
private static final int MAX_TASK_QUEUE_SIZE = 20000;
private static final int KEEP_ALIVE_TIME = 500;
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());
/**
* 整個seata服務的入口應用
*/
public static void main(String[] args) throws IOException {
//獲取所有傳的參數
ParameterParser parameterParser = new ParameterParser(args);
//初始化監聽指標組件
MetricsManager.get().init();
System.setProperty(ConfigurationKeys.STORE_MODE, parameterParser.getStoreMode());
RpcServer rpcServer = new RpcServer(WORKING_THREADS);
//server port
rpcServer.setListenPort(parameterParser.getPort());
UUIDGenerator.init(parameterParser.getServerNode());
//log store mode : file, db
SessionHolder.init(parameterParser.getStoreMode());
DefaultCoordinator coordinator = new DefaultCoordinator(rpcServer);
coordinator.init();
rpcServer.setHandler(coordinator);
//註冊關閉註銷執行方法
ShutdownHook.getInstance().addDisposable(coordinator);
//127.0.0.1 and 0.0.0.0 are not valid here.
if (NetUtil.isValidIp(parameterParser.getHost(), false)) {
XID.setIpAddress(parameterParser.getHost());
} else {
XID.setIpAddress(NetUtil.getLocalIp());
}
XID.setPort(rpcServer.getListenPort());
try {
//服務端啓動
rpcServer.init();
} catch (Throwable e) {
LOGGER.error("rpcServer init error:{}", e.getMessage(), e);
System.exit(-1);
}
System.exit(0);
}
}
RpcServer#init方法
/**
* Init.
* 服務端啓動接口
*/
@Override
public void init() {
super.init();
setChannelHandlers(RpcServer.this);
DefaultServerMessageListenerImpl defaultServerMessageListenerImpl = new DefaultServerMessageListenerImpl(
transactionMessageHandler);
defaultServerMessageListenerImpl.init();
defaultServerMessageListenerImpl.setServerMessageSender(this);
//進行監聽客戶發佈的消息
this.setServerMessageListener(defaultServerMessageListenerImpl);
//開啓服務端
super.start();
}
使用IDEA啓動Seata 服務端,會出現如下問題
io.seata.codec.protobuf.generated不存在,導致seata server啓動不了?
出現這個問題是protobuf協議自動生成的代碼在0.8.1已經移除。
可以通過如下的方式臨時啓動Seata Server代碼
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>seata-codec-all</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>${project.groupId}</groupId>
<artifactId>seata-codec-protobuf</artifactId>
</exclusion>
</exclusions>
</dependency>
這樣子就可以啓動功能了,其他內容後面補充