撸源码过程中发现流程太长,看后面忘前面所以就把过程整理成了一张图,建议下载下图片来看
每个横向的泳道是es的不同模块
actionmodule是注册action的模块这个是es启动的时候做的不在主流程里面
粗体字是类,如果有多行下面是相关父类和接口
非粗体是相关方法,一个类中多个方法从上到下调用
下面是相关笔记
ActionModule中register了每个rest请求的Action
每个action实现了BaseRestHandler抽象类,里面主要的方法是handleRequest和prepareRequest,用户去实现prepareRequest方法返回RestChannelConsumer 去execute the action
每个prepareRequest中调用client的方法去处理request, request请求过来都经过handler然后交给client去处理,得到一个channel?这个地方调用了client中NodeClient,NodeClient实现了AbstractClient,里面有client的各种操作,execute, search , index等等
search模块中调用execute方法,execute中调用NodeClient doExecute方法,doExecute执行 executeLocally, executeLocally交给transportAction方法去执行,里面通过action得到transportAction?,然后调用transportAction execute方法
execute中交给了实现类TransportSearchAction 的doExecute方法去执行, 然后交给不同的SearchAsyncAction去做
SearchAsyncAction start之后先performFirstPhase然后注册监听进去, 得到结果之后onFirstPhaseResult,调用innerMoveToSecondPhase 去fetch即可
performFirstPhase中交给去searchTransportService去query,到这里action的事情完了,交给SearchTransportService了
SearchTransportService中是各种execute,然后交给TransportService(这个类很强大)实例sendRequest去
sendRequest交给asyncSender处理(这样做的意义?)然后交给本类的sendRequestInternal处理,然后里面交给这个类里面的sendLocalRequest和transport.sendRequest
TransportService中会register几个handler去处理不同的request,在registerRequestHandler方法中,SearchTransportService调用了register方法, sendLocalRequest中开始得handler去了,!!!这个地方设计很巧妙,可以在SearchTransportService的handler中看到具体是哪个searchService去执行的,但单独线程去执行的代码都在TransportService中,通过回调得到数据去,赞!
sendLocalRequest中声明了一个channel,在RequestHandlerRegistry中把result给到了这个channel的sendResponse中
进入到searchService中,会发现上面的不同的请求(qaf, qtf dfs)都交给这个类处理了,现在看的是executeFetchPhase,里面SearchContext(DefaultSearchContext)掌握了上下文信息结果也存在这个里面queryResult,SearchOperationListener会在search不同的执行时间进行操作监听,listener对象在INdexShard中创建的ShardSearchStats然后MeanMetric数据, 根据listener可以看出来loadOrExecuteQueryPhase是执行query的地方
进去看到QueryPhase类的execute方法是主要的lucene地方,执行方法是searcher.search(query, collector); 会把结果放在collector里面,然后queryResult.topDocs(topDocsCallable.call(), sortValueFormats); 把结果放在searchContext.queryResult中, 回到SearchService交给fetchPhase去做
fetchPhase execute中context.searcher().getIndexReader().leaves().get(readerIndex);得到id,然后通过StoredFieldVisitor的实现类FieldsVisitor得到原始数据,这说明,原始数据还是lucene做的
bind方法类似spring的IOC,把类注入,其他地方用的时候会自动加载
每个action的初始化函数里面controller.registerHandler就是告诉哪些请求会采用这个action处理