玩轉Elasticsearch源碼-使用Intellij IDEA和remote debug調試源代碼

開篇

學習源碼第一步就是搭建調試環境,但是看了網上大部分Elasticsearch調試方式都是配置各種環境變量然後直接啓動Main方法,而且還各種報錯。今天提供新的方式--remote debug來避免這些麻煩。

步驟

環境

首先要安裝jdk8,gradle和Intellij IDEA

源碼下載

拉取代碼,checkout到想要調試的版本(這裏切到v6.1.0,需要注意的是不同ES分支對gradle版本要求不一樣,可以到README文件中查看對應到gradle版本要求)

git clone [email protected]/elastic/elasticsearch
cd elasticsearch
git checkout v6.1.0

導入到IDEA

執行gradle idea,成功後會提示BUILD SUCCESSFUL,然後導入到IDEA

:test:fixtures:hdfs-fixture:idea
:test:fixtures:krb5kdc-fixture:ideaModule
:test:fixtures:krb5kdc-fixture:idea
:test:fixtures:old-elasticsearch:ideaModule
:test:fixtures:old-elasticsearch:idea

BUILD SUCCESSFUL

Total time: 2 mins 2.159 secs

使用gradle啓動Elasticsearch

gradle run --debug-jvm

執行成功後是這樣的,其中8000就是遠程debug端口image.png

配置remote debug

點擊IDEA的Edit Configurations,再點擊➕image.png
填寫主機和端口,Name是配置名稱,可以自定義(我這裏就填es),點OK保存配置image.png
搜一下源碼裏面Elasticsearch類,,看到Main方法,先打個斷點等會看效果image.png
最後再點下綠色小蟲子啓動debugimage.png
是不是在斷點停下來了image.png
跳過斷點再看下控制檯,是不是啓動日誌都出來了image.png
再驗證下是否啓動成功image.png

原理

一切源於被稱作 Agent 的東西。JVM有一種特性,可以允許外部的庫(Java或C++寫的libraries)在運行時注入到 JVM 中。這些外部的庫就稱作 Agents, 他們有能力修改運行中 .class 文件的內容。
這些 Agents 擁有的這些 JVM 的功能權限, 是在 JVM 內運行的 Java Code 所無法獲取的, 他們能用來做一些有趣的事情,比如修改運行中的源碼, 性能分析等。 像 JRebel 工具就是用了這些功能達到魔術般的效果。
傳遞一個 Agent Lib 給 JVM, 通過添加 agentlib:libname[=options] 格式的啓動參數即可辦到。像上面的遠程調試我們用的就是 -agentlib:jdwp=... 來引入 jdwp 這個 Agent 的。
jdwp 是一個 JVM 特定的 JDWP(Java Debug Wire Protocol) 可選實現,用來定義調試者與運行JVM之間的通訊,它的是通過 JVM 本地庫的 jdwp.so 或者 jdwp.dll 支持實現的。簡單來說, jdwp agent 會建立運行應用的 JVM 和調試者(本地或者遠程)之間的橋樑。既然他是一個Agent Library, 它就有能力攔截運行的代碼。
在 JVM 架構裏, debugging 功能在 JVM 本身的內部是找不到的,它是一種抽象到外部工具的方式(也稱作調試者 debugger)。這些調試工具或者運行在 JVM 的本地 或者在遠程。這是一種解耦,模塊化的架構。

關於Agent還有很多值得研究的細節,甚至基於JVMTI自己實現。參考https://www.ibm.com/developerworks/cn/java/j-lo-jpda2/index.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章