Elasticsearch 8.9启动时构建接收Rest请求的hander过程源码

  • 一、main方式入口
  • 二、Elasticsearch初始化第三阶段
    • 1、构造node节点对象时构造restController
    • 2、在node构建对象最后执行初始化RestHanders的操作
  • 三、以注册在hander中的RestGetIndicesAction对象为例介绍
    • 1、继承了BaseRestHandler,routes方法做路由规则,父类调用子类的prepareRequest实现
    • 2、BaseRestHandler实现的是RestHandler接口

一、main方式入口

路径:org.elasticsearch.bootstrap.Elasticsearch

  /*** 启动 elasticsearch 的主入口点。*/public static void main(final String[] args) {Bootstrap bootstrap = initPhase1();assert bootstrap != null;try {initPhase2(bootstrap);initPhase3(bootstrap);} catch (NodeValidationException e) {bootstrap.exitWithNodeValidationException(e);} catch (Throwable t) {bootstrap.exitWithUnknownException(t);}}

这里初始化会有三个初始化阶段。可以直接看initPhase3

二、Elasticsearch初始化第三阶段

 /***初始化的第三阶段*阶段 3 包含初始化安全管理器后的所有内容。到目前为止,该系统一直是单线程的。此阶段可以生成线程、写入日志,并受安全管理器策略的约束。* 在第 3 阶段结束时,系统已准备好接受请求,主线程已准备好终止。这意味着:*    节点组件已构建并启动*    清理已完成(例如安全设置已关闭)*    除主线程外,至少有一个线程处于活动状态,并且在主线程终止后将保持活动状态*    已通知父 CLI 进程系统已准备就绪*/private static void initPhase3(Bootstrap bootstrap) throws IOException, NodeValidationException {//调用checkLucene()函数进行Lucene的检查checkLucene();//创建一个Node对象,并重写validateNodeBeforeAcceptingRequests方法,用于在接受请求之前进行节点验证。Node node = new Node(bootstrap.environment()) {@Overrideprotected void validateNodeBeforeAcceptingRequests(final BootstrapContext context,final BoundTransportAddress boundTransportAddress,List<BootstrapCheck> checks) throws NodeValidationException {BootstrapChecks.check(context, boundTransportAddress, checks);}};//使用bootstrap.spawner()和之前创建的node对象实例化一个Elasticsearch对象,并将其赋值给INSTANCE变量。INSTANCE = new Elasticsearch(bootstrap.spawner(), node);//关闭安全设置IOUtils.close(bootstrap.secureSettings());//启动INSTANCE对象,node会启动,并保持一个存活线程INSTANCE.start();//如果命令行参数指定了daemonize,则移除控制台输出的日志配置。if (bootstrap.args().daemonize()) {LogConfigurator.removeConsoleAppender();}//发送CLI标记,表示服务器已经准备好接受请求。bootstrap.sendCliMarker(BootstrapInfo.SERVER_READY_MARKER);//如果命令行参数指定了daemonize,则关闭流;否则,启动CLI监视线程。if (bootstrap.args().daemonize()) {bootstrap.closeStreams();} else {startCliMonitorThread(System.in);}}

其中INSTANCE.start();如下,代表node启动,并且存活线程运行

private void start() throws NodeValidationException {node.start();keepAliveThread.start();}

1、构造node节点对象时构造restController

public Node(Environment environment) {this(environment, PluginsService.getPluginsServiceCtor(environment), true);}
/*** Constructs a node* 节点的初始化*/protected Node(final Environment initialEnvironment,final Function<Settings, PluginsService> pluginServiceCtor,boolean forbidPrivateIndexSettings) {//省略代码。。。。//里面会初始化restControllerActionModule actionModule = new ActionModule(settings,clusterModule.getIndexNameExpressionResolver(),settingsModule.getIndexScopedSettings(),settingsModule.getClusterSettings(),settingsModule.getSettingsFilter(),threadPool,pluginsService.filterPlugins(ActionPlugin.class),client,circuitBreakerService,usageService,systemIndices,tracer,clusterService,reservedStateHandlers);modules.add(actionModule);//restController存入到networkModule,而NetworkModule是用于处理注册和绑定所有网络相关类的模块//末尾有 actionModule.initRestHandlers初始化handerfinal RestController restController = actionModule.getRestController();final NetworkModule networkModule = new NetworkModule(settings,pluginsService.filterPlugins(NetworkPlugin.class),threadPool,bigArrays,pageCacheRecycler,circuitBreakerService,namedWriteableRegistry,xContentRegistry,networkService,restController,actionModule::copyRequestHeadersToThreadContext,clusterService.getClusterSettings(),tracer);//省略代码。。。。//初始化Rest的HandleractionModule.initRestHandlers(() -> clusterService.state().nodesIfRecovered());}

2、在node构建对象最后执行初始化RestHanders的操作

  public void initRestHandlers(Supplier<DiscoveryNodes> nodesInCluster) {//省略代码。。。这里只选几个经常用到的registerHandler.accept(new RestGetIndicesAction());registerHandler.accept(new RestIndicesStatsAction());registerHandler.accept(new RestCreateIndexAction());    registerHandler.accept(new RestDeleteIndexAction());registerHandler.accept(new RestGetIndexTemplateAction());registerHandler.accept(new RestPutIndexTemplateAction());registerHandler.accept(new RestDeleteIndexTemplateAction());registerHandler.accept(new RestPutMappingAction());registerHandler.accept(new RestGetMappingAction());registerHandler.accept(new RestGetFieldMappingAction());registerHandler.accept(new RestIndexAction());registerHandler.accept(new RestSearchAction(restController.getSearchUsageHolder()));//省略代码}

三、以注册在hander中的RestGetIndicesAction对象为例介绍


/*** The REST handler for get index and head index APIs.* 用于获取索引和头索引 API 的 REST 处理程序。*/
@ServerlessScope(Scope.PUBLIC)
public class RestGetIndicesAction extends BaseRestHandler {//代表路由匹配规则,通过这个规则知道要调用这个实例,每一个实例路由规则都是不一样的@Overridepublic List<Route> routes() {return List.of(new Route(GET, "/{index}"), new Route(HEAD, "/{index}"));}@Overridepublic RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException {// starting with 7.0 we don't include types by default in the response to GET requestsif (request.getRestApiVersion() == RestApiVersion.V_7&& request.hasParam(INCLUDE_TYPE_NAME_PARAMETER)&& request.method().equals(GET)) {deprecationLogger.compatibleCritical("get_indices_with_types", TYPES_DEPRECATION_MESSAGE);}String[] indices = Strings.splitStringByCommaToArray(request.param("index"));final GetIndexRequest getIndexRequest = new GetIndexRequest();getIndexRequest.indices(indices);getIndexRequest.indicesOptions(IndicesOptions.fromRequest(request, getIndexRequest.indicesOptions()));getIndexRequest.local(request.paramAsBoolean("local", getIndexRequest.local()));getIndexRequest.masterNodeTimeout(request.paramAsTime("master_timeout", getIndexRequest.masterNodeTimeout()));getIndexRequest.humanReadable(request.paramAsBoolean("human", false));getIndexRequest.includeDefaults(request.paramAsBoolean("include_defaults", false));getIndexRequest.features(GetIndexRequest.Feature.fromRequest(request));final var httpChannel = request.getHttpChannel();return channel -> new RestCancellableNodeClient(client, httpChannel).admin().indices().getIndex(getIndexRequest, new RestChunkedToXContentListener<>(channel));}}

1、继承了BaseRestHandler,routes方法做路由规则,父类调用子类的prepareRequest实现

public abstract class BaseRestHandler implements RestHandler {/*** {@inheritDoc}*/@Overridepublic abstract List<Route> routes();@Overridepublic final void handleRequest(RestRequest request, RestChannel channel, NodeClient client) throws Exception {//调用prepareRequest方法,准备请求以供执行,并且会对请求参数进行处理。final RestChannelConsumer action = prepareRequest(request, client);//过滤未使用的参数,将未使用的参数收集到一个有序集合中。final SortedSet<String> unconsumedParams = request.unconsumedParams().stream().filter(p -> responseParams(request.getRestApiVersion()).contains(p) == false).collect(Collectors.toCollection(TreeSet::new));//验证未使用的参数是否有效,如果存在无效参数,则抛出IllegalArgumentException异常。if (unconsumedParams.isEmpty() == false) {final Set<String> candidateParams = new HashSet<>();candidateParams.addAll(request.consumedParams());candidateParams.addAll(responseParams(request.getRestApiVersion()));throw new IllegalArgumentException(unrecognized(request, unconsumedParams, candidateParams, "parameter"));}//验证请求是否包含请求体,并且请求体是否已被消耗,如果不满足条件,则抛出IllegalArgumentException异常。if (request.hasContent() && request.isContentConsumed() == false) {throw new IllegalArgumentException("request [" + request.method() + " " + request.path() + "] does not support having a body");}//增加使用计数usageCount.increment();//执行action,将结果传递给channel。action.accept(channel);}/***准备要执行的请求。* 实现应在返回可运行对象以进行实际执行之前使用所有请求参数。* 未使用的参数将立即终止请求的执行。* 但是,某些参数仅用于处理响应;实现可以覆盖 {@link BaseRestHandlerresponseParams()} 来指示此类参数。*/protected abstract RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException;
}    

2、BaseRestHandler实现的是RestHandler接口

/*** Handler for REST requests*/
@FunctionalInterface
public interface RestHandler {/*** 处理rest请求*/void handleRequest(RestRequest request, RestChannel channel, NodeClient client) throws Exception;/*** 此 RestHandler 负责处理的 {@link 路由} 的列表。*/default List<Route> routes() {return Collections.emptyList();}}

其中调用RestHandler接口的handerRequest的上游是

 @Overridepublic void handleRequest(RestRequest request, RestChannel channel, NodeClient client) throws Exception {//使用 OPTIONS 方法的请求应在其他地方处理,而不是通过调用 {@code RestHandlerhandleRequest} 使用 OPTIONS 方法的 HTTP 请求绕过 authn,因此此健全性检查可防止调度未经身份验证的请求if (request.method() == Method.OPTIONS) {handleException(request,channel,new ElasticsearchSecurityException("Cannot dispatch OPTIONS request, as they are not authenticated"));return;}if (enabled == false) {doHandleRequest(request, channel, client);return;}}private void doHandleRequest(RestRequest request, RestChannel channel, NodeClient client) throws Exception {threadContext.sanitizeHeaders();// operator privileges can short circuit to return a non-successful responseif (operatorPrivilegesService.checkRest(restHandler, request, channel, threadContext)) {try {restHandler.handleRequest(request, channel, client);} catch (Exception e) {logger.debug(() -> format("Request handling failed for REST request [%s]", request.uri()), e);throw e;}}}

其他注册在hander中的API和RestGetIndicesAction类似

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/112598.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt作业九

1、思维导图 2、作业 widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTimer> #include <QTime> #include <QTimerEvent> #include <QTextToSpeech>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAME…

Linux网络-UDP/TCP协议详解

Linux网络-UDP/TCP协议详解 2023/10/17 14:32:49 Linux网络-UDP/TCP协议详解 零、前言一、UDP协议二、TCP协议 1、应答机制2、序号机制3、超时重传机制4、连接管理机制 三次握手四次挥手5、理解CLOSE_WAIT状态6、理解TIME_WAIT状态7、流量控制8、滑动窗口 丢包问题9、拥塞控制…

数据库系统>并发控制

1.数据库系统架构设计知识 1.1练习题1 在数据库系统中&#xff0c;“事务”是访问数据库并可能更新各种数据项的一个程序执行单元。为了保证数据完整性&#xff0c;要求数据库系统维护事务的原子性、一致性、隔离性和持久性。针对事务的这4种特性&#xff0c;考虑以下的架构设…

Linux - 还不懂 gdb 调试器?(调试软件)

前言 当前&#xff0c;我们可以使用 make/makefile 来程序化执行代码文件&#xff1b;可以使用 gcc/g 等编译器来编译代码&#xff1b;可以使用 vim 编辑器来编写代码&#xff1b;其实在 Linux 当中还有一个工具&#xff0c;可以实现调试工作&#xff0c;这个工具就是 -- gdb。…

CSS 效果 圆形里一个文字居中

效果实现源码&#xff1a; 宽度&#xff0c;高度必须确认&#xff0c;且相等 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><style>.circlew {width: 45px;height: 45p…

PHPEXCEL解决行数超过65536不显示问题

起因自然是导出数据到excel文件时&#xff0c;数据缺少现象。 百度讲解是将xls文件另存为xlsx文件。 除了这里的原因&#xff0c;还有一点是phpExcel存在两个写入类PHPExcel_Writer_Excel2007和PHPExcel_Writer_Excel5&#xff0c;而只有PHPExcel_Writer_Excel2007支持超过65…

可信执行环境简介:ARM 的 TrustZone

目录 可信执行环境安全世界与普通世界 - 上下文切换机制ARMv7 中的异常处理ARMv8 中的异常处理 信任区商业实施TrustZone 本身的漏洞高通Trustonic 信任区强化的弱点结论声明 可信执行环境 具有信任区的 ARM 处理器实现了架构安全性每个物理处理器内核提供两个虚拟的扩展 核心…

nextTick实现原理

答题思路&#xff1a; 此题实际考查vue异步更新策略说出vue是怎么通过异步、批量的方式更新以提高性能的最后把源码中实现说一下 回答范例&#xff1a; vue有个批量、异步更新策略&#xff0c;数据变化时&#xff0c;vue开启一个队列&#xff0c;并缓冲在同一事件循环中发生的…

计数排序详解

一、什么是计数排序&#xff1f; 计数排序(CountSort)是一个非基于比较的排序算法&#xff0c;该算法于1954年由 Harold H. Seward 提出。它的优势在于在对一定范围内的整数排序时&#xff0c;它的复杂度为Ο(nk)&#xff08;其中k是整数的范围&#xff09;&#xff0c;快于任何…

【Rust日报】2023-10-19 使用 Rust 编写编译器

Arete Engine 0.1.0 alpha 版发布 Arete Engine 最近发布了 0.1.0 alpha 版,这是一个预发布版本,其中包括 Rust 和 C两种语言编写的性能演示 Demo。这个版本主要目的是展示 Arete Engine 的基本功能,还缺失许多特性。值得一提的是,此版本硬编码了所有任务(包括 culling 和 mode…

华为OD 停车场车辆统计(100分)【java】A卷+B卷

华为OD统一考试A卷+B卷 新题库说明 你收到的链接上面会标注A卷还是B卷。目前大部分收到的都是B卷。 B卷对应20022部分考题以及新出的题目,A卷对应的是新出的题目。 我将持续更新最新题目 获取更多免费题目可前往夸克网盘下载,请点击以下链接进入: 我用夸克网盘分享了「华为O…

HCIP静态路由综合实验

题目&#xff1a; 步骤&#xff1a; 第一步&#xff1a;搭建上图所示拓扑; 第二步&#xff1a;为路由器接口配置IP地址&#xff1b; R1&#xff1a; [R1]display current-configuration intinterface GigabitEthernet0/0/0ip address 192.168.1.1 255.255.255.252 interfa…

数据分析:密度图

目前拥有的数据如图&#xff0c;三列分别对应瑕疵种类&#xff0c;对应的置信 度&#xff0c;x方向坐标。 现在想要做的事是观看瑕疵种类和置信度之间的关系。 要显示数据分布的集中程度&#xff0c;可以使用以下几种常见的图形来观察&#xff1a; 1、箱线图&#xff08;Box P…

c++数组教程

今天来讲讲数组 什么是数组&#xff1a; 我们来看一道题目&#xff1a; 【题目部分】 输入n个数,逆序输出它们. 输入 第一行一个整数n (0 < n < 60 ) 第二行n个整数 输出 一行,n个整数。 输入样例 1 5 1 6 2 8 4 输出样例 1 4 8 2 6 1 这下就难住很多人了&…

笙默考试管理系统-MyExamTest----codemirror(39)

笙默考试管理系统-MyExamTest----codemirror&#xff08;39&#xff09; 目录 一、 笙默考试管理系统-MyExamTest 二、 笙默考试管理系统-MyExamTest 三、 笙默考试管理系统-MyExamTest 四、 笙默考试管理系统-MyExamTest 五、 笙默考试管理系统-MyExamTest 笙默考试…

【数据可视化】—大屏数据可视化展示

【数据可视化】—大屏数据可视化展示 一、数据可视化 数据可视化的目的&#xff1a;借助于图形化工具&#xff0c;清晰有效的传达与沟通信息。 数据可视化可以把数据从冰冷的数字转换成图形&#xff0c;揭示蕴含在数据中的规律和道理。 二、 免费数据可视化库 Echarts 百度…

Kurento多对多webrtc会议搭建测试

环境ubuntu18.04 KMS版本6.13.0 多对多通信demo7.0.0 KMS运行起来后&#xff0c;通过运行它的一个个demo&#xff0c;来实现不同的功能&#xff0c;它的demo很多如下&#xff1a; https://github.com/Kurento 里面有一对一&#xff0c;多对多&#xff0c;还有一些特效的demo。…

Android13 实现有线网络和wifi共存

Android13 实现有线网络和wifi共存 文章目录 Android13 实现有线网络和wifi共存一、前言二、修改代码&#xff1a;1、ConnectivityService.java2、NetworkFactoryImpl.java3、Android11 和Android13 修改代码目录对比&#xff1a;4、如果只修改部分代码的后果只修改 Connectivi…

提升医院安全的关键利器——医院安全(不良)事件报告系统源码

医院是人们寻求医疗服务和康复的场所&#xff0c;安全是医院运营的基石。然而&#xff0c;医疗过程中不可避免地会出现不良事件&#xff0c;如药物错误、手术事故等。为了及时发现、评估和解决这些问题&#xff0c;医院安全&#xff08;不良&#xff09;事件报告系统应运而生。…

聊聊Android线程优化这件事

一、背景 在日常开发APP的过程中&#xff0c;难免需要使用第二方库和第三方库来帮助开发者快速实现一些功能&#xff0c;提高开发效率。但是&#xff0c;这些库也可能会给线程带来一定的压力&#xff0c;主要表现在以下几个方面&#xff1a; 线程数量增多&#xff1a;一些库可…