(三)elasticsearch 源码之启动流程分析

news/2024/4/16 2:30:20

https://www.cnblogs.com/darcy-yuan/p/17007635.html

1.前面我们在《(一)elasticsearch 编译和启动》和 《(二)elasticsearch 源码目录 》简单了解下es(elasticsearch,下同),现在我们来看下启动代码

下面是启动流程图,我们按照流程图的顺序依次描述

2.启动流程

org.elasticsearch.bootstrap.Elasticsearchpublic static void main(final String[] args) throws Exception {overrideDnsCachePolicyProperties();/** We want the JVM to think there is a security manager installed so that if internal policy decisions that would be based on the* presence of a security manager or lack thereof act as if there is a security manager present (e.g., DNS cache policy). This* forces such policies to take effect immediately.*/System.setSecurityManager(new SecurityManager() {@Overridepublic void checkPermission(Permission perm) {// grant all permissions so that we can later set the security manager to the one that we want}});LogConfigurator.registerErrorListener();final Elasticsearch elasticsearch = new Elasticsearch();int status = main(args, elasticsearch, Terminal.DEFAULT);if (status != ExitCodes.OK) {exit(status);}}

后续执行 Elasticsearch.execute -> Elasticsearch.init -> Bootstrap.init

org.elasticsearch.bootstrap.Bootstrapstatic void init(final boolean foreground,final Path pidFile,final boolean quiet,final Environment initialEnv) throws BootstrapException, NodeValidationException, UserException {// force the class initializer for BootstrapInfo to run before// the security manager is installedBootstrapInfo.init();INSTANCE = new Bootstrap();// 安全配置文件final SecureSettings keystore = loadSecureSettings(initialEnv);final Environment environment = createEnvironment(pidFile, keystore, initialEnv.settings(), initialEnv.configFile());LogConfigurator.setNodeName(Node.NODE_NAME_SETTING.get(environment.settings()));try {LogConfigurator.configure(environment);} catch (IOException e) {throw new BootstrapException(e);}if (JavaVersion.current().compareTo(JavaVersion.parse("11")) < 0) {final String message = String.format(Locale.ROOT,"future versions of Elasticsearch will require Java 11; " +"your Java version from [%s] does not meet this requirement",System.getProperty("java.home"));new DeprecationLogger(LogManager.getLogger(Bootstrap.class)).deprecated(message);}// 处理pidFileif (environment.pidFile() != null) {try {PidFile.create(environment.pidFile(), true);} catch (IOException e) {throw new BootstrapException(e);}}// 如果是后台启动,则不打印日志final boolean closeStandardStreams = (foreground == false) || quiet;try {if (closeStandardStreams) {final Logger rootLogger = LogManager.getRootLogger();final Appender maybeConsoleAppender = Loggers.findAppender(rootLogger, ConsoleAppender.class);if (maybeConsoleAppender != null) {Loggers.removeAppender(rootLogger, maybeConsoleAppender);}closeSystOut();}// fail if somebody replaced the lucene jarscheckLucene();// 通用异常捕获// install the default uncaught exception handler; must be done before security is// initialized as we do not want to grant the runtime permission// setDefaultUncaughtExceptionHandlerThread.setDefaultUncaughtExceptionHandler(new ElasticsearchUncaughtExceptionHandler());INSTANCE.setup(true, environment);try {// any secure settings must be read during node constructionIOUtils.close(keystore);} catch (IOException e) {throw new BootstrapException(e);}INSTANCE.start();if (closeStandardStreams) {closeSysError();}}

这里我们可以关注下  INSTANCE.setup(true, environment);

org.elasticsearch.bootstrap.Bootstrapprivate void setup(boolean addShutdownHook, Environment environment) throws BootstrapException {Settings settings = environment.settings();try {spawner.spawnNativeControllers(environment);} catch (IOException e) {throw new BootstrapException(e);}// 检查一些mlock设定initializeNatives(environment.tmpFile(),BootstrapSettings.MEMORY_LOCK_SETTING.get(settings),BootstrapSettings.SYSTEM_CALL_FILTER_SETTING.get(settings),BootstrapSettings.CTRLHANDLER_SETTING.get(settings));// 探针// initialize probes before the security manager is installedinitializeProbes();if (addShutdownHook) {Runtime.getRuntime().addShutdownHook(new Thread() {@Overridepublic void run() {try {IOUtils.close(node, spawner);LoggerContext context = (LoggerContext) LogManager.getContext(false);Configurator.shutdown(context);if (node != null && node.awaitClose(10, TimeUnit.SECONDS) == false) {throw new IllegalStateException("Node didn't stop within 10 seconds. " +"Any outstanding requests or tasks might get killed.");}} catch (IOException ex) {throw new ElasticsearchException("failed to stop node", ex);} catch (InterruptedException e) {LogManager.getLogger(Bootstrap.class).warn("Thread got interrupted while waiting for the node to shutdown.");Thread.currentThread().interrupt();}}});}try {// 检查类加载的一些问题// look for jar hellfinal Logger logger = LogManager.getLogger(JarHell.class);JarHell.checkJarHell(logger::debug);} catch (IOException | URISyntaxException e) {throw new BootstrapException(e);}// Log ifconfig output before SecurityManager is installedIfConfig.logIfNecessary();// 安全处理// install SM after natives, shutdown hooks, etc.try {Security.configure(environment, BootstrapSettings.SECURITY_FILTER_BAD_DEFAULTS_SETTING.get(settings));} catch (IOException | NoSuchAlgorithmException e) {throw new BootstrapException(e);}node = new Node(environment) {@Overrideprotected void validateNodeBeforeAcceptingRequests(final BootstrapContext context,final BoundTransportAddress boundTransportAddress, List<BootstrapCheck> checks) throws NodeValidationException {BootstrapChecks.check(context, boundTransportAddress, checks);}};}

最后一句 node = new Node(environment) 初始化了节点,里面做了许多工作

org.elasticsearch.node.Nodeprotected Node(final Environment environment, Collection<Class<? extends Plugin>> classpathPlugins, boolean forbidPrivateIndexSettings) {...// 打印jvm信息final JvmInfo jvmInfo = JvmInfo.jvmInfo();logger.info("version[{}], pid[{}], build[{}/{}/{}/{}], OS[{}/{}/{}], JVM[{}/{}/{}/{}]",Build.CURRENT.getQualifiedVersion(),jvmInfo.pid(),Build.CURRENT.flavor().displayName(),Build.CURRENT.type().displayName(),Build.CURRENT.hash(),Build.CURRENT.date(),Constants.OS_NAME,Constants.OS_VERSION,Constants.OS_ARCH,Constants.JVM_VENDOR,Constants.JVM_NAME,Constants.JAVA_VERSION,Constants.JVM_VERSION);
...// 初始化各类服务,以及他们相关的依赖this.pluginsService = new PluginsService(tmpSettings, environment.configFile(), environment.modulesFile(),environment.pluginsFile(), classpathPlugins);final Settings settings = pluginsService.updatedSettings();final Set<DiscoveryNodeRole> possibleRoles = Stream.concat(DiscoveryNodeRole.BUILT_IN_ROLES.stream(),pluginsService.filterPlugins(Plugin.class).stream().map(Plugin::getRoles).flatMap(Set::stream)).collect(Collectors.toSet());DiscoveryNode.setPossibleRoles(possibleRoles);localNodeFactory = new LocalNodeFactory(settings, nodeEnvironment.nodeId());
...// guice注入modules.add(b -> {b.bind(Node.class).toInstance(this);b.bind(NodeService.class).toInstance(nodeService);b.bind(NamedXContentRegistry.class).toInstance(xContentRegistry);b.bind(PluginsService.class).toInstance(pluginsService);b.bind(Client.class).toInstance(client);b.bind(NodeClient.class).toInstance(client);b.bind(Environment.class).toInstance(this.environment);b.bind(ThreadPool.class).toInstance(threadPool);

es 使用 guice注入框架,guice是个非常轻量级的依赖注入框架,既然各个组件都已经注入好了,我们现在可以启动了。

INSTANCE.start -> Bootstrap.start

org.elasticsearch.bootstrap.Bootstrapprivate void start() throws NodeValidationException {node.start();keepAliveThread.start();}

 node.start中启动各个组件。es中的各个组件继承了 AbstractLifecycleComponent。start方法会调用组件的doStart方法。

org.elasticsearch.node.Nodepublic Node start() throws NodeValidationException {if (!lifecycle.moveToStarted()) {return this;}logger.info("starting ...");pluginLifecycleComponents.forEach(LifecycleComponent::start);injector.getInstance(MappingUpdatedAction.class).setClient(client);injector.getInstance(IndicesService.class).start();injector.getInstance(IndicesClusterStateService.class).start();injector.getInstance(SnapshotsService.class).start();injector.getInstance(SnapshotShardsService.class).start();injector.getInstance(SearchService.class).start();nodeService.getMonitorService().start();final ClusterService clusterService = injector.getInstance(ClusterService.class);final NodeConnectionsService nodeConnectionsService = injector.getInstance(NodeConnectionsService.class);nodeConnectionsService.start();clusterService.setNodeConnectionsService(nodeConnectionsService);...

具体的我们看两个比较重要的服务  transportService.start();

org.elasticsearch.transport.TransportService@Overrideprotected void doStart() {transport.setMessageListener(this);connectionManager.addListener(this);// 建立网络连接transport.start();if (transport.boundAddress() != null && logger.isInfoEnabled()) {logger.info("{}", transport.boundAddress());for (Map.Entry<String, BoundTransportAddress> entry : transport.profileBoundAddresses().entrySet()) {logger.info("profile [{}]: {}", entry.getKey(), entry.getValue());}}localNode = localNodeFactory.apply(transport.boundAddress());if (connectToRemoteCluster) {// here we start to connect to the remote clustersremoteClusterService.initializeRemoteClusters();}}

启动transport的实现类是 SecurityNetty4HttpServerTransport

 另一个比较重要的服务,discovery.start(),具体实现类是 Coordinator

org.elasticsearch.cluster.coordination.Coordinator@Overrideprotected void doStart() {synchronized (mutex) {CoordinationState.PersistedState persistedState = persistedStateSupplier.get();coordinationState.set(new CoordinationState(getLocalNode(), persistedState, electionStrategy));peerFinder.setCurrentTerm(getCurrentTerm());configuredHostsResolver.start();final ClusterState lastAcceptedState = coordinationState.get().getLastAcceptedState();if (lastAcceptedState.metaData().clusterUUIDCommitted()) {logger.info("cluster UUID [{}]", lastAcceptedState.metaData().clusterUUID());}final VotingConfiguration votingConfiguration = lastAcceptedState.getLastCommittedConfiguration();if (singleNodeDiscovery &&votingConfiguration.isEmpty() == false &&votingConfiguration.hasQuorum(Collections.singleton(getLocalNode().getId())) == false) {throw new IllegalStateException("cannot start with [" + DiscoveryModule.DISCOVERY_TYPE_SETTING.getKey() + "] set to [" +DiscoveryModule.SINGLE_NODE_DISCOVERY_TYPE + "] when local node " + getLocalNode() +" does not have quorum in voting configuration " + votingConfiguration);}...

http://www.ppmy.cn/news/1344982.html

相关文章

【C语言】三子棋游戏实现代码

目录 1.三子棋代码功能介绍 2.三子棋游戏实现步骤 ①打印菜单栏 ②判断是否进入三子棋游戏 ③三子棋游戏基本函数实现 &#xff08;1&#xff09;清空&#xff08;初始化&#xff09;棋盘函数实现 &#xff08;2&#xff09;打印棋盘函数实现 &#xff08;3&#xff0…

django+flask网上购物商城系统的设计与实现python-vue

全球经济在快速的发展&#xff0c;中国更是进步飞速&#xff0c;这使得国内的互联网技术进入了发展的高峰时期&#xff0c;这让中外资本不断转向互联网这个大市场[3]。在这个信息高度发达的现在&#xff0c;利用网络进行信息管理改革已经成为了人们追捧的一种趋势。“网上购物系…

mac检查CPU温度和风扇速度软件:Macs Fan Control Pro 1.5.17中文版

Macs Fan Control Pro for Mac是一款专业的电脑风扇控制工具&#xff0c;旨在帮助Mac用户有效控制电脑的风扇速度&#xff0c;提高电脑的运行效率和稳定性。 软件下载&#xff1a;Macs Fan Control Pro 1.5.17中文版 该软件支持多种风扇控制模式和预设方案&#xff0c;用户可以…

vue全屏,退出全屏、监听ESC退出全屏

一、所有内容全屏 <template><div class"Quanping"><el-button style"position: absolute;top: 0%;right: 0%;background-color: palegreen" click"toFullOrExit()">{{ isFull ? 关闭全屏 : 全屏 }}</el-button></…

“掌握温度,感知湿度,一触即知!”DHT11温湿度传感器,为您的生活增添一份关怀与精准。#非标协议【下】

“掌握温度&#xff0c;感知湿度&#xff0c;一触即知&#xff01;”DHT11温湿度传感器&#xff0c;为您的生活增添一份关怀与精准。#非标协议【下】 前言预备知识1.DHT11温湿度传感器初识1.1产品概述1.2与51单片机接线1.3数据传送逻辑和数据格式 2.发送时序检测DHT11温湿度传感…

【AI数字人-论文】Geneface论文

文章目录 前言pipelineaudio-to-motionMotion domain adaptation可视化 Motion-to-imageHead-NeRFTorso-NeRF 结果对比 前言 语音驱动的说话人视频合成旨在根据一段输入的语音&#xff0c;合成对应的目标人脸说话视频。高质量的说话人视频需要满足两个目标&#xff1a; &#…

护眼灯色温多少合适?推荐五款合适色温的护眼台灯

很多人在购买台灯之后只会根据周围环境灯光的明暗调节亮度&#xff0c;对于色温的了解并不多&#xff0c;不知道色温应该调节到什么数值比较合适&#xff0c;有些人也根本没有意识到色温在影响人情绪方面起着重要作用&#xff0c;接下来就一起来看一下色温的标准。 一、什么色…

软件系统架构的演变历史介绍

个人浅见&#xff0c;不喜勿喷&#xff0c;非常感谢。 软件系统架构的演变历史与计算机技术的发展紧密相连。从最早的单一大型计算机&#xff0c;到个人计算机的兴起&#xff0c;再到互联网和云计算的普及&#xff0c;软件系统架构经历了多次重大的变革。以下是软件系统…

ubuntu开机报错/dev/nume0n1p2:clean

一、前提 1、当你平时用的图站或者linux系统出现这个问题&#xff0c;首先看看你的显卡有没有换位置。 我的就是项目电脑&#xff0c;同事换了显卡位置&#xff0c;我不知道&#xff0c;当我在这个基础上继续做的时候&#xff0c;出了问题。 2、当你是第一次装显卡&#xff…

strtok的使用

Strtok&#xff1a;原型char *strtok(char s[], const char *delim); s为要分解的字符&#xff0c;delim为分隔符字符&#xff08;如果传入字符串&#xff0c;则传入的字符串中每个字符均为分割符&#xff09;。首次调用时&#xff0c;s指向要分解的字符串&#xff0c;之后再次…

axios下载文件打开失败解决

在axios的then中创建了a标签下载文件完成之后&#xff0c;发现下载的文件打不开。 解决方法 设置responseType: blob 注意&#xff01;&#xff01;&#xff01;这个是和headers同级别的&#xff0c;不是在headers里面的

数据结构-图的最小生成树

最小生成树介绍 最小生成树(Minimum Cost Spanning Tree)是代价最小的连通网的生成树&#xff0c;即该生成树上的边的权值和最小 最小生成树的性质&#xff1a; 必须使用且仅使用连通网中的n-1条边来联结网络中的n个顶点&#xff1b; 不能使用产生回路的边&#xff1b; 各…

qt学习:arm摄像头+c调用v412框架驱动+qt调用v412框架驱动 显示摄像头画面

目录 跟内核进行数据通信的函数 编程步骤 c代码 头文件 打开摄像头文件 /dev/videox 获取当前主机上&#xff08;开发板&#xff09;摄像头列表信息 设置当前摄像头的画面格式 比如说 设置 采集图像的宽度为640 高度 480 在内核空间中&#xff0c;申请一个缓冲区队列…

财务数据处理问题及解决方案分享

一、平台介绍 财务自营计费主要承接京东自营数据在整个供应链中由C端转B端的功能实现&#xff0c;在整个供应链中属于靠后的阶段了&#xff0c;系统主要功能是计费和向B端的汇总。 二、问题描述 近年来自营计费数据量大增&#xff0c;有百亿的数据量&#xff0c;一天中汇总占…

Nacos安装,服务注册,负载均衡配置,权重配置以及环境隔离

1. 安装 首先从官网下载 nacos 安装包&#xff0c;注意是下载 nacos-server Nacos官网 | Nacos 官方社区 | Nacos 下载 | Nacos 下载完毕后&#xff0c;解压找到文件夹bin&#xff0c;文本打开startup.cmd 修改配置如下 然后双击 startup.cmd 启动 nacos服务&#xff0c;默认…

如何利用边缘计算网关进行机床数据采集,以提高数据采集的效率和准确性-天拓四方

边缘计算网关集成了数据采集、处理和传输功能的嵌入式设备。它位于传感器和执行器组成的设备层与云计算平台之间&#xff0c;能够实时处理和响应本地设备的数据请求&#xff0c;减轻云平台的压力&#xff0c;提高数据处理的速度和效率。同时&#xff0c;边缘计算网关还可以将处…

作业:单身狗1

思路&#xff1a; 一&#xff1a;题目一开始就规定了这个数组的标准——只有一个数字出现一次&#xff0c;其他数字都是成对出现的&#xff0c;因此&#xff0c;重点就是如何排除成对的数&#xff0c;和保留单独的数 二&#xff1a;^的特点&#xff1a;相同为0&#xff0c;不…

React 实现表单组件

表单是html的基础元素&#xff0c;接下来我会用React实现一个表单组件。支持包括输入状态管理&#xff0c;表单验证&#xff0c;错误信息展示&#xff0c;表单提交&#xff0c;动态表单元素等功能。 数据状态 表单元素的输入状态管理&#xff0c;可以基于react state 实现。 …

1、将 ChatGPT 集成到数据科学工作流程中:提示和最佳实践

将 ChatGPT 集成到数据科学工作流程中:提示和最佳实践 希望将 ChatGPT 集成到您的数据科学工作流程中吗?这是一个利用 ChatGPT 进行数据科学的提示的实践。 ChatGPT、其继任者 GPT-4 及其开源替代品非常成功。开发人员和数据科学家都希望提高工作效率,并使用 ChatGPT 来简…

ffmpeg命令生成器

FFmpeg 快速入门&#xff1a;命令行详解、工具、教程、电子书 – 码中人的博客FFmpeg 是一个强大的命令行工具&#xff0c;可以用来处理音频、视频、字幕等多媒体文件。本文介绍了 FFmpeg 的基本用法、一些常用的命令行参数&#xff0c;以及常用的可视化工具。https://blog.mzh…
最新文章