Arthas 定位 Dubbo 手动注册 Eureka 异常
作者 | java_keith
來源|阿里巴巴云原生公眾號
很久沒有寫技術分享博客,因為發現一個好的工具確實有點忍不住分享一下,畢竟獨樂樂不如眾樂樂。> 這里需要說的主角就是 Artahs。> Arthas 使用文檔很詳細,我這里主要記錄一下使用 Arthas 的一點總結。
使用背景
在一個大的團隊里面,會因為很多歷史原因或客觀因素導致技術棧并不統一,我們就遇到這么一個問題。老項目是使用 Dubbo 框架的 Dubbo 協議進行服務交互,有新的項目是使用 Springcloud 體系的 Feignclient 框架的 Http 協議進行交互。那么就需要解決兩個問題。
-
問題 1 是 Dubbo 服務需要支持 Dubbo 協議又需要支撐 Http 協議。
-
問題 2 是 Feignclient 框架能夠無損調用 Dubbo 服務的 Http 協議(無損指的是 Dubbo 對 Feignclient 調用方能夠做到服務動態感知,負載均衡不需要做二次開發)。
解決思路
有了以上的目標,我們就需要想辦法解決問題。解決第一個問題倒是比較容易,Dubbo 本身就提供的 Http 協議暴漏。也就是將老工程 Dubbo 升級、配置兩種協議問題一就這么解決了。
但是針對問題 2,我們可以羅列一下遇到的問題。Dubbo 注冊使用的是 zk 注冊中心,Springcloud 工程使用 Eureka 注冊中心。這里順帶也要贊美一下 Feignclient 框架,Feignclient 接入服務的門檻很低,這樣兼容了很多語言、環境等帶來的差異,也就是說只要是 http 協議的接口 Feignclient 就能調用。到這里實際上通過 Feignclient 直接調用 Dubbo 服務暴漏的 Http 協議接口是能夠走的通,只不過沒法做到負載均衡,失敗轉移等能力。說了這么多總結一下吧。
-
現在通過 Feignclient 直連 Dubbo 框架工程的 Http 協議能夠正常執行。
-
分布式環境下需要解決直連的弊端(無法負載均衡,無法失敗轉移,無法動態擴容等等) 好在通過分析了 Eureka 源碼以后打開了另一個大門,Eureka 實際上是獨立的組件,而且提供手動注冊服務的能力(即使沒有修改源碼就有了)。現在解決思路就是在 Dubbo 工程里面引入 Eureka 組件,手動將服務注冊到 Eureak 以便 Feignclient 能夠無損調用。
主角(Arthas)登場
為了將 Dubbo 框架工程提供注冊 Eureka 的能力,并且能夠做到優雅上線和下線。我們主要是借助了 Dubbo 的 Spi 擴展能力中的 Container 擴展。代碼如下:
class EurekaDubboContainer implements Container {...}有了以上代碼還需要做一件重要的事情,就是聲明 Container 的全路徑。META-INF/dubbo/org.apache.dubbo.container.Container:xxx=com.xxx.XxxContainer,當時我們配置這里的代碼 spring=com.xxx.EurekaDubboContainer,當所有準備好了以后我們啟動工程,發現無異常輸出,進程完美。但是 Deignclient 怎么也無法調用。最主要是啟動過程中沒有任何異常輸出,經過大量論證后,就在快絕望的時候,我發現了 Arthas,Arthas 可以查看內存中對象屬性值以及執行對象的方法,我欣喜若狂。通過之前對 Dubbo 注冊過程源碼分析:
com.alibaba.dubbo.common.extension.ExtensionLoader#loadFile } catch (Throwable t) {IllegalStateException e = new IllegalStateException("Failed to load extension class(interface: " + type + ", class line: " + line + ") in " + url + ", cause: " + t.getMessage(), t);exceptions.put(line, e); }在 Dubbo 啟動過程,會從 Jar 包中掃描配置的 META-INF 中配置的 Container,在加載的時候這個異常是直接存放在了 Loader 類的域中,猜測可能是為了解決 Container 隔離所以異常并沒有拋出。當前主要目標還是分析為啥我定義的擴展容易沒有啟動。部署 Arthas 以后我開始了分析之路。
-
sc -d *.EurekaDubboContainer 發現類已經正常加載,說明有被 Load 加載。
-
jad *.EurekaDubboContainer 發現加載的類代碼也是在正常(排除包不對的可能)。
-
ognl ‘#loader=@com.alibaba.dubbo.container.Main@loader,#loader.cachedInstances’ 這里發現了問題,如果是正常被 Load 的 Container 會被存在到 ExtensionLoader 的 CachedInstances 域中(默認的 Spring,log4j存在),但是我自定義的 Container 竟然沒找到。
-
ognl ‘#loader=@com.alibaba.dubbo.container.Main@loader,#loader.exceptions’ 這里發現了之所有沒有加載成功的原因,在 Exceptions 中有聲明。
通過以上分析,問題非常明顯了,在 META-INF 中指定的 Key 重復了。還是沒深入理解 Dubbo 中的 Spi 文檔上的‘xxx’是自定義的意思。到這里修改 Key 以后一切按照計劃執行。
結束
通過一波操作,我們發現從技術角度出發,其實沒有解決不了的問題,只是需要多想一想,多想想辦法總可以找到的。包括使用 Arthas 上 Ognl 如何查看 Load 實例中的非靜態域,直接獲取是無法獲取的,因為沒有存在在 Arthas 上下文中,所以變通一下思路:通過 Main 的靜態域獲取實例,再通過實例變量獲取非靜態域的值。技術沒有終止,愿你我一同進步。為開源貢獻微薄的力量。若對細節有興趣的朋友,可留言交流。
Arthas 有獎征文正在進行中!
為了讓更多開發者開始用上 Arthas 這個 Java 診斷神器,今年 3 月 26 日,Arthas 社區聯合 JetBrains 推出?Arthas 有獎征文活動:**聊聊這些年你和 Arthas 之間的那些事兒。**活動已進行至第七期,點擊鏈接即可參與:http://alibabacloud.mikecrm.com/9khcRrs,歡迎大家踴躍投稿,參與即有可能獲獎!
總結
以上是生活随笔為你收集整理的Arthas 定位 Dubbo 手动注册 Eureka 异常的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ChaosBlade 在工商银行混沌工程
- 下一篇: 我参与阿里巴巴 ASoC-Seata 的