阅读Elasticsearch源代码 – 启动Elasticsearch
本文是《2021年圣诞日历》第18篇文章。
首先
最近,我有机会开发Elasticsearch的自定义插件,并且意识到我对Elasticsearch的理解还不够,所以我从这个季度开始和团队成员一起举办内部Elasticsearch源代码阅读学习会。
在本文中,我们总结了以前的学习小组内容的概要,并整理了Elasticsearch的启动过程。
这次使用的Elasticsearch版本是7.14,在启动之前有一些准备工作(例如环境变量设置),但在这里略去了。请事先谅解我的知识不足。如果您能给出关于文章内容的建议,例如对于这个地方应该这样理解,我将非常高兴!
Elasticsearch启动的概述
Elasticsearch的启动过程大致包括以下步骤。
-
- org.elasticsearch.bootstrap.Elasticsearch的main()方法
-
- org.elasticsearch.bootstrap.Bootstrap类
- org.elasticsearch.node.Node类
首先,我们将解释Elasticsearch的入口点。通过elasticsearch的启动脚本(bin/elasticsearch)来确认,入口点是org.elasticsearch.bootstrap.Elasticsearch。
exec \
"$JAVA" \
"$XSHARE" \
$ES_JAVA_OPTS \
-Des.path.home="$ES_HOME" \
-Des.path.conf="$ES_PATH_CONF" \
-Des.distribution.flavor="$ES_DISTRIBUTION_FLAVOR" \
-Des.distribution.type="$ES_DISTRIBUTION_TYPE" \
-Des.bundled_jdk="$ES_BUNDLED_JDK" \
-cp "$ES_CLASSPATH" \
org.elasticsearch.bootstrap.Elasticsearch \
"$@" <<<"$KEYSTORE_PASSWORD"
org.elasticsearch.bootstrap.Elasticsearch#main() –> org.elasticsearch.bootstrap.Elasticsearch的主函数()
entry point的代码如下:
需要做的事情如下所述。
-
- 起動コマンドからDNS Cache Policyを設定するなら、DNS Cache Policyをオーバーライドする
- SecurityManagerを設定、checkPermissionで全部の権限を許可
Command#mainWithoutErrorHandling
パラメータをパースしてterminalを設置して、EnvironmentAwareCommandのexecute()を実行(Commandクラスの抽象executeメソッドをオーバーライト)
EnvironmentAwareCommand#execute
パラメータからSettingを判別、Settingがなければvm optionsからpath.data、path.home、path.logsをSettingに配置
execute(terminal, options, createEnv(settings))を呼び出し
EnvironmentAwareCommand#createEnv
prepareEnvironmentを経由elasticsearch.ymlをロードして、Environmentを作成
Elasticsearch#execute
daemonizer/pidFile/quietの値を取得、Bootstrapのinitを呼び出し
org.elasticsearch.bootstrap.Bootstrap
弹性搜索的引导程序
初始化代码很多,只保留链接:
https://github.com/elastic/elasticsearch/blob/fc519e380029c6daecc950802435f7266f08708e/server/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java#L334
首先创建一个Bootstrap实例,然后启动KeepAlive线程。
private final CountDownLatch keepAliveLatch = new CountDownLatch(1);
private final Thread keepAliveThread;
private final Spawner spawner = new Spawner();
/** creates a new instance */
Bootstrap() {
keepAliveThread = new Thread(new Runnable() {
@Override
public void run() {
try {
//count
keepAliveLatch.await();
} catch (InterruptedException e) {
// bail out
}
}
}, "elasticsearch[keepAlive/" + Version.CURRENT + "]");
keepAliveThread.setDaemon(false);
// keep this thread alive (non daemon thread) until we shutdown
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
//thread終了時、KeepAliveLatchが0になって、keepAliveThread終了
keepAliveLatch.countDown();
}
});
}
JVM 的终止流程如下:
1. 当不存在用户线程时,开始 JVM 的终止。
2. JVM 结束所有的守护线程。
3. JVM 终止。
保持活动线程在设置为 CountDownLatch 和用户线程的情况下设置。
所以,这里的流程是
2. 执行 shutdownHook
3. 执行 keepAliveLatch.countDown()
4. 当 KeepAliveLatch 为0时,终止 keepAliveThread
5. JVM 终止
启动KeepAlive线程后,关于Bootstrap的init()函数的大致过程如下:
-
- SettingとconfigによってES実行時Environmentを作る
-
- セキュリティとログ周りの設定
keystoreのセキュリティ設定をロードする。keystoreファイルない時に作って保存する。keystoreファイルある時に復号化して、keystoreを更新する
setNodeName ログをプリント時Node名を設定、log4j2.propertiesの設定ファイルからログの設定をロード
PIDファイルがあるかどうかを確認、なければ作る、現在のpidを書き込む
Luceneのバージョンを確認
setDefaultUncaughtExceptionHandlerでCatchされない例外の処理方法を設置
-
- INSTANCE.setup(true, environment);INSTANCE.start();
Nodeインスタンスを作るため準備して、Nodeインスタンスを作って、Nodeインスタンスを起動
想法等
-
- Elasticsearchの起動だけでこんなプロセスがあることを理解できて、細かい粒度でElasticsearchの仕組みを把握できるようになりました。
- CountDownLatchなどのプロセス調査により、Javaのマルチスレッドプログラミングに詳しくなりました。