- 版本: 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