Elasticsearch 5.x 源碼分析(9)聊聊ES的IoC 和 ClassLoader

這兩周做的事情比較雜踪少,所以看代碼的點也稍微有點分散,不過我盡量用手頭的例子來把這些東西串起來糠涛。
做的事情還是上兩周那件事:我想攔截ES的Request 和Response援奢,統(tǒng)計我自己想要的指標并保存,那么需要完成以下3件事情:

  1. 怎么攔截
  2. 除了Request 和Response 外如何獲取container 里的其他Service
  3. 如何去跑我自己的攔截代碼的邏輯

怎么攔截

其實這個話題我在上一篇(Elasticsearch 5.x 源碼分析(8)用plugin來攔截Request脱羡、Response 的可行性調研)已經詳細介紹了萝究,大家有興趣可以往回翻一下看看就好了免都,只是這種辦法最大的缺點就是不是很美觀,埋的點也很多帆竹,甚至有時可能需要入侵ES的源代碼绕娘,這幾天搗鼓的是另外一個方法:AspectJ 攔截。

根據上一篇的思路栽连,RestSearchTemplateAction 調用的是

channel -> client.execute(SearchTemplateAction.INSTANCE, searchTemplateRequest, new ActionListener<SearchTemplateResponse>() 

RestSearchAction調用的是

channel -> client.search(searchRequest, new ActionListener<SearchResponse>()

RestIndexAction調用的是

client.index(indexRequest, new ActionListener<IndexResponse>()

剩下RestBulkAction調用的是

channel -> client.bulk(bulkRequest, new ActionListener<BulkResponse>()

上面說到的最終會調用

public final <Request extends ActionRequest, Response extends ActionResponse, RequestBuilder extends ActionRequestBuilder<Request, Response, RequestBuilder>> void execute(
            Action<Request, Response, RequestBuilder> action, Request request, ActionListener<Response> listener) 

因此AspectJ的話只需要攔截這個方法即可
大致攔截語句如下

    /**
     * 攔截所有RestSearchAction , RestSearchTemplateAction , IndexAction 和 BulkAction 的請求
     * @param pjp
     * @throws Throwable
     */
    @Around("execution(* org.elasticsearch.client.support.AbstractClient.execute(org.elasticsearch.action.Action, org.elasticsearch.action.ActionRequest, org.elasticsearch.action.ActionListener))")
    public void doTrace(final ProceedingJoinPoint pjp) throws Throwable {
        Object[] args = pjp.getArgs();
        if(isWorking && args != null && args.length == 3) {
            handleArg(args);
        }
        pjp.proceed(args);
    }

如何獲得ES的IoC 注入Service 類

好了险领,加了攔截點那么其實你可以為所欲為了化撕,可是寺旺,當我僅僅只想拿到當前Elasticsearch 實例的clusterName的時候,卻遇到麻煩了洪燥。
大家都知道ES為了效率和輕便熔恢,是用的是Google的 Guice 來實現依賴注入脐湾,可是Guice 的bind 同時需要一個Injector 實例才能完成getInstance,也就是說如果我需要拿到ES 的clusterService.getClusterName()方法叙淌,那么我首先要先想辦法拿到clusterService所bind 的那個Injector 才行秤掌。

那首當其沖先看Node.java,其中注冊Service的代碼塊在構造方法處


并且Node開放了一個API出來


OK ,那去找Node實例,往上找到Bootstrap.java 代碼


這里持有了一個node實例鹰霍,那就拿Bootstrap 實例好了闻鉴,可惜不開放,此路不通茂洒!

接著換一種思路孟岛,找傳進來的配置Settings不就可以了


那繼續(xù)往上找,找到environment 的初始化


再去找Settings類督勺,希望它內存保留一份副本渠羞,結果沒卵用,好吧玷氏,ES的安全措施做的還是不錯的堵未,這種配置的東西基本不讓外面調用或攔截有入侵的機會腋舌。那就是說如果我想攔截代碼盏触,想拿到ES的Service基本是不可能的。


如何去跑我的那段攔截代碼

如果就一兩行代碼的話那就完全沒必要這么復雜了块饺,但是我攔截的邏輯比較重赞辩,依賴的包都十幾個,這就有點尷尬了授艰,最好的機制還是自己弄個classLoader 去加載我自己的依賴辨嗽,這樣的話也不至于和ES本身的代碼會有沖突(logger 的API都好幾個...)。
這里先拋個銀子淮腾,話說上面那個問題糟需,有些人也會想到說:其實你自己隨便弄個plugin屉佳,然后把ES注入給我的Service我全部暴露出來不就行了? 因此它偏偏就不行洲押,原因就是武花,ES的plugin 和Modules 加載都是采用獨自的classLoader實現的。
因此這里我遇到了新的問題:

  1. 我的攔截邏輯要么用ES 的classLoader 來加載杈帐,要么用我自己的classLoader加載体箕,但是無論如何我都無法讀取到plugin 里面的類
  2. 像RestSearchTemplateAction,SearchTemplateRequest挑童,SearchTemplateResponse這些類都是打在 lang-mustashe.jar 里面的累铅,是屬于module plugin 存在,因此無論我是哪種classLoader加載站叼,我都是無法攔截并強轉成這些對象來做文章娃兽。
    那么我想到的辦法只能是反射了,比如這樣

至于說是否需要用到自己的classLoader 尽楔,那就視乎你自己的邏輯復雜程度换薄,像我的話就是把所有的邏輯都封裝出去,然后用獨自的classLoader來加載翔试,避免重讀轻要,自己搞classLoader的話就切記注意一點,千萬要catch所有的throwable垦缅,避免JVM 掛了冲泥。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市壁涎,隨后出現的幾起案子凡恍,更是在濱河造成了極大的恐慌,老刑警劉巖怔球,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嚼酝,死亡現場離奇詭異,居然都是意外死亡竟坛,警方通過查閱死者的電腦和手機闽巩,發(fā)現死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來担汤,“玉大人涎跨,你說我怎么就攤上這事≌钙纾” “怎么了隅很?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長率碾。 經常有香客問我叔营,道長屋彪,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任绒尊,我火速辦了婚禮撼班,結果婚禮上,老公的妹妹穿的比我還像新娘垒酬。我一直安慰自己砰嘁,他們只是感情好,可當我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布勘究。 她就那樣靜靜地躺著矮湘,像睡著了一般。 火紅的嫁衣襯著肌膚如雪口糕。 梳的紋絲不亂的頭發(fā)上缅阳,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天,我揣著相機與錄音景描,去河邊找鬼十办。 笑死,一個胖子當著我的面吹牛超棺,可吹牛的內容都是我干的向族。 我是一名探鬼主播,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼棠绘,長吁一口氣:“原來是場噩夢啊……” “哼件相!你這毒婦竟也來了?” 一聲冷哼從身側響起氧苍,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤夜矗,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后让虐,有當地人在樹林里發(fā)現了一具尸體紊撕,經...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年赡突,在試婚紗的時候發(fā)現自己被綠了对扶。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡麸俘,死狀恐怖辩稽,靈堂內的尸體忽然破棺而出惧笛,到底是詐尸還是另有隱情从媚,我是刑警寧澤,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布患整,位于F島的核電站拜效,受9級特大地震影響喷众,放射性物質發(fā)生泄漏。R本人自食惡果不足惜紧憾,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一到千、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧赴穗,春花似錦憔四、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至甸赃,卻和暖如春柿汛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背埠对。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工络断, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人项玛。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓貌笨,卻偏偏與公主長得像,于是被迫代替她去往敵國和親襟沮。 傳聞我的和親對象是個殘疾皇子躁绸,可洞房花燭夜當晚...
    茶點故事閱讀 44,619評論 2 354

推薦閱讀更多精彩內容