- 版本: ElasticSearch 5.4.4
- Lucene版本: 6.5.1
- java: open jdk 1.8
框架入口
ES的入口位於以下路徑:
org.elasticsearch.bootstrap.ElasticSearch
當框架啓動時候,主要會進行加載安全設置、內部檢查以及外部檢查。
安全設置
考慮到某些配置文件是明文寫的,而es涉及到的一些數據文件需要加密,並保存在config/elasticsearch.keystore文件
System.setSecurityManager(new SecurityManager() {
@Override
public void checkPermission(Permission perm) {
// grant all permissions so that we can later set the security manager to the one that we want
}
});
檢查內部環境
- lucene版本檢查
- 檢測jar衝突,發現痛處退出進程。
檢測外部環境
- 執行對象: Node
- 檢查對象: 所有的檢查被封裝在BootstarpChecks中,在早起es中,除了正常的環境檢查還會對輸入參數進行檢查,將不合理的參數提示給用戶。檢查對象包括: 堆大小檢查、文件描述檢查、內存鎖定檢查、最大線程數量檢查、最大虛擬內存檢查、最大文件大小檢查、虛擬內存區域內存最大數量檢查、JVM client模式檢查、串行收集檢查、系統過濾器檢查等等。
es中的進程只允許使用物理內存,避免使用交換分區,原因是目前在生產環境中已經不是因爲內存不足而需要交換到硬盤上,對於服務器來說交換到硬盤會產生更多的問題。bootstarp.memory_lock爲鎖定內存。
啓動內部模塊
啓動Node類中的各個子模塊:
// org.elasticsearch.bootstrap.Bootstarp;
INSTANCE.start();
整個es是通過Guice框架來進行管理的,因此在啓動時,節點各個模塊會通過Guice獲取實例
injector.getInstance(MappingUpdatedAction.class).setClient(client);
injector.getInstance(IndicesService.class).start();
injector.getInstance(IndicesClusterStateService.class).start();
injector.getInstance(IndicesTTLService.class).start();
injector.getInstance(SnapshotsService.class).start();
injector.getInstance(SnapshotShardsService.class).start();
injector.getInstance(RoutingService.class).start();
injector.getInstance(SearchService.class).start();
injector.getInstance(MonitorService.class).start();
這裏面涉及到了很多的子模塊,其本質就是初始化內部數據、創建線程池啓動線程池。
啓動keepalive線程
調用keepAliveThread.start()啓動keepalive,線程本身不做具體工作。主要線程執行完後會退出,keepalive是唯一的用戶線程,作用是保持進行運行。
在java中進程必須有至少一個用戶線程,不然就會退出,這個線程就是爲了保持進程存在的。
節點關閉流程
ES進程會捕獲SIGTERM信號(kill命令默認信號)進行處理,調用各個模塊的stop方法
Bootstarp中的stop方法如下;
static void stop() throws IOException {
try {
IOUtils.close(INSTANCE.node, INSTANCE.spawner);
} finally {
INSTANCE.keepAliveLatch.countDown();
}
}
關閉流程分析
每個模塊的service都實現了,doStop與doClose方法,用於正常關閉,先調用doStop在執行doClose。service關閉是有順序的,如下:
- 關閉快照和HTTPSERVER,不在響應rest請求。
- 關閉集羣拓撲管理,不在響應ping請求。
- 關閉網絡模塊,讓節點離線。
- 執行各個插件的關閉流程。
- 關閉IndicesService