ES源碼版本 7.10java
啓動過程當中的action
好比咱們有個搜索請求:web
curl -X GET "localhost:9200/blogs/_search?pretty" -H 'Content-Type: application/json' -d'
{
"query": {
"function_score": {
"query": {
"match": {
"content": "elasticsearch"
}
},
"field_value_factor": {
"field": "likes",
"factor": 2,
"modifier": "sqrt",
"missing": 1
}
}
}
}
'
這個請求ES是如何找到對應的模塊去處理呢?答案是ES在啓動過程當中註冊了請求的URL和對應的Action的綁定關係。json
RestSearchAction.java
微信
好比上面,RestSearchAction就是對應/{index}/_search
這個URL模板的處理Action,ES裏有不少繼承自BaseRestHandler
的Action綁定到不一樣的Action上。本篇就以/{index}/_search
爲例來講明。數據結構
具體是怎麼關聯的呢?咱們繼續分析。app
ES在啓動的時候要初始化Node類。curl
Bootstrap.java
elasticsearch
在構造函數裏會調用ActionModule類,這個類就是ES的Action管理的核心處理類,後面講搜索過程當中的Action部分它也會出現。Node構造函數裏會調用ActionModule類的initRestHandlers方法來註冊。函數
ActionModule.java
url
initRestHandlers這個方法裏會調用RestController的registerHandler方法完成註冊。
RestController.java
handlers.insertOrUpdate方法內部就不深刻了,這裏實際上是用了字典樹的數據結構(Trie),存儲path(/{index}/_search
)和Handler的對應關係。Trie的核心思想是空間換時間,利用字符串的公共前綴來下降查詢時間的開銷以達到提升效率的目的。
因此在請求階段查找的時候,也一樣是根據url path去查找對應的handler。這部分在下個章節會提到。
還有一個TransportAction須要說明下。在ActionModule類的setupActions方法,會將Action和對應的TransportAction註冊到actions對象中。這個Action指的是SearchAction(search場景下),以下圖所示:
ActionModule.java
其實底層就是放在一個Map裏創建一個映射關係。請求的時候去這個Map裏找。
請求過程當中的action
瞭解了Action相關的啓動加載流程,下面咱們來看一個查詢的調用鏈路,順藤摸瓜,看看一個查詢請求是怎麼應用到Action的。
首先全部的請求入口都是netty,準確來講對外的請求都是基於netty4封裝的HTTP server。而後server分發請求。這部分其實更多的是netty和http相關的通用邏輯,這裏不作詳細介紹了。HTTP server的分發邏輯最終會調用到RestController
類的dispatchRequest方法
RestController.java
tryAllHandlers方法前面這個循環是用來把http請求的頭部信息傳遞到ES底層調用,從而作一些特殊處理。header裏的key是ES定義的,value咱們能夠本身指定。好比X-Opaque-Id
這個key,若是咱們應用端請求的時候賦值了,能夠用來跟蹤從http請求到底層我的任務的執行鏈路。
RestController.java
接着看,好比仍是上面那個搜索請求:
curl -X GET "localhost:9200/blogs/_search?pretty" -H 'Content-Type: application/json' -d'
{
"query": {
"function_score": {
"query": {
"match": {
"content": "elasticsearch"
}
},
"field_value_factor": {
"field": "likes",
"factor": 2,
"modifier": "sqrt",
"missing": 1
}
}
}
}
'
RestController.java
這段代碼能夠根據個人請求的path,這裏是
/blogs/_search
找到對應
/{index}/_search
的RestHandler
,這個查找就是根據url path去Trie樹查找。而後經過dispatchRequest方法分發給找到的Handler處理。這個方法會統一調用到BaseRestHandler
這個基類進行處理
BaseRestHandler.java
根據前面的path(/{index}/_search),咱們知道上圖中找到的這個action必然是RestSearchAction
,而後根據這個類重載的prepareRequest方法能夠找到accept的執行邏輯。
RestSearchAction.java
這裏最終會調用NodeClient
類找到action(注意這裏的action和上面的action不是一個東西,這裏的action是searchAction)對應的TransPortAction,前面在啓動章節說過,在ActionModule中會將Action和對應的TransportAction註冊到actions對象中。如今就是從actions對象(是個Map)中拿到對應的TransportAction,並並執行其execute()方法。
在NodeClient中會根據傳入的Action參數從actions獲取在ActionModule中註冊的TransportAction,並執行其execute()方法
TransportAction後面的的邏輯,就是具體的ES查詢邏輯處理了。這個後面會有專門的系列文章。這裏再也不詳述。
上面的調用鏈路,能夠用一個時序圖表示
本文分享自微信公衆號 - 犀牛飼養員的技術筆記(coder_start_up)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。