[6]elasticsearch源码深入分析——API源码分析

上一篇中我们讲到ElasticSearch中分为五类API(查看API,文档API,搜索API,索引API,集群API),这篇我们继续研究cat API中的重要编码结构。

RestController的继承关系

从Node实例化的过程中,我们知道ActionModule是Node提供Rest请求功能的主要模块。RestController的实例是在ActionModule实例化的时候传入的重要参数之一,RestController是API提供服务的关键类之一,我们先从这个类开始梳理Rest API的加载逻辑。

RestController的继承关系

RestController继承自AbstractComponent,实现了HttpServerTransport.Dispatcher接口。

抽象类AbstractComponent,没什么复杂的逻辑,就是定义了一个基类Logger,一个Deprecation的Logger,Deprecation的Logger用处是打印settings配置中不提倡的参数设定(提醒ElasticSearch的使用者),该抽象类只有两个关于日志的方法:

  • 调用AbstractComponent的logDeprecatedSetting(String settingName, String alternativeName)方法就能提示启动ElasticSearch的用户参数中的settingName是弃用的,可以用方法中的参数alternativeName来代替。
  • 调用AbstractComponent的logRemovedSetting(String settingName, String alternativeName)方法能提示用户settingName参数已经被移除,可用alternativeName来代替。

因为设计思路是将dispatchRequest这样的方法设计成接口,而发送请求逻辑分组率属于HttpServerTransport,所以将Dispatcher接口设计成HttpServerTransport的内部接口,这样所有的Dispatcher的实现类都会带有HttpServerTransport接口的标记。

HttpServerTransport接口又实现了LifecycleComponent接口,LifecycleComponent接口标记了生命周期状态相关的逻辑,如下图:

LifecycleComponent中的抽象方法

其中Releasable类是ElasticSearch自己封装JDK1.7中的AutoCloseable。从LifecycleComponent的方法中可以看出该接口主要标记了Component的生命周期状态相关,当然还有添加和移除生命周期监听器,主要还是看LifecycleComponent的实现类是怎么实现这些标记的逻辑的。

下面我们查看HttpServerTransport接口的逻辑,这个接口也不复杂,在HttpServerTransport接口中则主要配置了http线程的线程名前缀,绑定的Address,Http信息和状态。

在HttpServerTransport的内部接口Dispatcher中,主要是两个方法:

  • void dispatchRequest(RestRequest request, RestChannel channel, ThreadContext threadContext),发送request到相关处理请求程序,如果request不能被任何处理请求程序处理则直接响应给RestChannel
  • void dispatchBadRequest(RestRequest request, RestChannel channel, ThreadContext threadContext, Throwable cause),发送一个失败的RestRequest,用在request是残缺的情况下。

RestController中的主要方法

梳理了RestController的父类结构,终于到了梳理RestController本身的时候了。RestController中最关键的方法是:

  • dispatchRequest(RestRequest request, RestChannel channel, ThreadContext threadContext)
  • registerHandler(RestRequest.Method method, String path, RestHandler handler)
registerHadler方法

RestController的registerHandler方法做了哪些事呢?registerHandler的主要功能是当注册了一个REST处理程序后,如果提供的方法和路径之一匹配请求时,执行处理程序。

查看源码我们会发现主要做了两个操作

  • registerHandler方法将BaseRestHandler的实例注册到usageService中,UsageService是监控ElasticSearch特性的服务(UsageService的主要逻辑是统计了RestController实例中的handler的占用数,底层是用的LongAdder,其适用于统计计数的场景),简而言之就是让Node的usageService加入对参数中handler和path的监控。
  • 更新handlers中的参数。因为RestController中持有一个PathTrie<MethodHandlers>类型的handler,每次注册都更新这个handler里面的值。
dispatchRequest方法

这个方法是实现了Dispatcher接口中的dispatchRequest方法。

由于ElasticSearch没有用到任何WEB框架,rest请求底层都是使用Netty实现的,收到的请求都是从ElasticSearch的transport-netty4模块里面发送给ElasticSearch的核心的。

  • transport-netty4模块的Netty4HttpRequestHandler类的channelRead0(ChannelHandlerContext ctx, Object msg)方法接受到其请求,然后发送给Netty4HttpServerTransport的dispathchRequest方法
  • Netty4HttpServerTransport再转发给RestController的DispatchRequest方法

RestController中dispatchRequest,遍历所有可能的处理程序,发送请求:

    Iterator<MethodHandlers> allHandlers = getAllHandlers(request);
    for (Iterator<MethodHandlers> it = allHandlers; it.hasNext(); ) {
        final Optional<RestHandler> mHandler = Optional.ofNullable(it.next()).flatMap(mh -> mh.getHandler(request.method()));
        requestHandled = dispatchRequest(request, channel, client, mHandler);
        if (requestHandled) {
            break;
        }
    }

如果返回的requestHandled为false,则返回失败的handleBadRequest(request, channel);

CAT API

cat aliases API

aliases显示有关当前配置的别名的信息,包括过滤器和路由信息。

GET /_cat/aliases?v

可能的响应:

alias  index filter routing.index routing.search
alias1 test1 -      -            -
alias2 test1 *      -            -
alias3 test1 -      1            1
alias4 test1 -      2            1,2

输出显示alias2已经配置了一个过滤器,以及alias3alias4中的特定路由配置。

如果只想获取有关特定别名的信息,则可以使用逗号分隔格式指定别名作为URL参数,例如,/_cat/aliases/aliases/alias1,alias2

REST请求是通过准备一个channel消费者(RestChannelConsumer)来处理的,Node在接收到aliases catAPI请求后,转发到RestAliasAction的doCatRequest方法,该方法会先确定这个请求是否是来自本地。RestAliasAction类的doCatRequest方法会返回一个RestChannelConsumer。

RestAliasAction类的doCatRequest方法接收两个参数RestRequest和NodeClient。

doCatRequest方法

这里的NodeClient是在本地节点上执行操作的Client。继承关系如下图:

NodeClient的继承关系

其中Client接口提供了一个用于对集群执行actions或操作的接口。客户可以从一个org.elasticsearch.node.node检索开始,或远程连接使用一个或多个节点org.elasticsearch.client.transport.transportclient

而NodeClient的admin方法是取得AbstractClient.Admin.IndicesAdmin实例,通过参数“索引别名请求(getAliasesRequest)”和“通知结果监听器(new RestResponseListener<GetAliasesResponse>(channel))”来获取特定索引或按名称存在的特定索引别名。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容