遠端debug除錯java程式碼
該系列介紹一些java開發中常用的一些小技巧,多小呢,從不會到會只需要一篇文章這麼小。這一篇介紹如何使用jdk自帶的擴充套件包配合Intellij IDEA實現遠端debug。
專案中經常會有出現這樣的問題,會令程式設計師抓狂:關鍵程式碼段沒有列印日誌,本地環境正常生產環境卻又問題…這時候,遠端debug可能會啟動作用。
1 準備用於debug的程式碼
準備一個RestController用於接收請求,最後可以通過本地斷點驗證是否成功開啟了遠端debug
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
專案使用springboot和maven構建,依賴就省略了,使用springboot提供的maven打包外掛,方便我們打包成可執行的jar。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
2 使用maven外掛打包成jar
3 準備啟動指令碼
1 |
|
- 使用java -jar的方式啟動程式,並且添加了一串特殊的引數,這是我們能夠開啟遠端debug的關鍵,以-開頭的引數是jvm的標準啟動引數,關於jvm啟動引數相關的知識可以先去其他部落格瞭解。
- -agentlib:libname[=options], 用於裝載本地lib包。在這條指令中便是載入了jdwp(Java Debug Wire Protocol)這個用於遠端除錯java的擴充套件包。而transport=dt_socket,server=y,suspend=n,address=64057這些便是jdwp裝載時的定製引數,詳細的引數作用可以搜尋jdwp進行了解。我們需要關心的只有address=64057這個引數選項,本地除錯程式使用64057埠與其通訊,從而遠端除錯。
4 配置IDEA
- 與指令碼中的指令完全一致
- 遠端jar包執行的host,由於我的jar執行在本地,所以使用的是localhost,一般線上環境自然是修改為線上的地址
- 與遠端jar包進行互動的埠號,idea會根據指令自動幫我們輸入
- 選擇與遠端jar包一致的原生代碼
請務必保證遠端jar包的程式碼與原生代碼一致!!!
5 驗證
儲存第4步的配置後,先執行指令碼讓遠端的jar包跑起來,再在IDEA中執行remote-debug
如上便代表連線執行成功了
在本地打上斷點,訪問localhost:8080/test
可以在本地看到堆疊資訊,大功告成。一行指令便完成了遠端除錯。
遠端除錯
遠端除錯分為主動連線除錯,和被動連線除錯。這裡以Eclipse為例。
主動連線除錯:服務端配置監控埠,本地IDE連線遠端監聽埠進行除錯,一般除錯問題用這種方式。
被動連線除錯:本地IDE監聽某埠,等待遠端連線本地埠。一般用於遠端服務啟動不了,啟動時連線到本地除錯分析。
主動連線除錯
首先需要遠端服務配置啟動指令碼:
JAVA_OPTS="$JAVA_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000"
如果是啟動jar包,指令:
java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000 -jar test.jar
這裡-Xdebug是通知JVM工作在DEBUG模式下,-Xrunjdwp是通知JVM使用(java debug wire protocol)來執行除錯環境。transport是監聽Socket埠連線方式(也可以dt_shmem共享記憶體方式,但限於windows機器,並且服務提供端和除錯端只能位於同一臺機)。server=y表示當前是除錯服務端,=n表示當前是除錯客戶端。suspend=n表示啟動時不中斷(如果啟動時中斷,一般用於除錯啟動不了的問題)。address=8000表示本地監聽8000埠。
遠端服務(tomcat/jboss)啟動成功後,本地Eclipse對需要除錯的地方打上斷點,然後專案右鍵啟動遠端除錯:Debug as->Debug Configurations->Remote Java Application。Host為遠端主機IP,Port為遠端監聽除錯埠,Connection Type為:Standard(Socket Attach),如圖:
點選Debug,然後打斷點,遠端服務執行到斷點處本地就會中斷,然後進行除錯。
被動連線除錯
首先需要Eclipse配置監聽,如主動連線除錯的Eclipse配置圖片,Connection Type選擇:Standard(Socket Listen),配置本地監聽埠,比如預設8000。點選Debug開始等待遠端連線除錯。
然後配置遠端服務啟動指令碼:
JAVA_OPTS="$JAVA_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,address=127.0.0.1:8000,suspend=y"
如果是除錯jar包,指令:
java -Xdebug -Xrunjdwp:transport=dt_socket,address=127.0.0.1:8000,suspend=y -jar remoting-debug.jar
引數含義和主動連線除錯一樣,只是這裡suspend=y表示啟動時就中斷,需要連線本地IDE除錯啟動。address=ip:port,ip需要修改為本地的對外IP。
這樣遠端專案啟動時就連線到本地,方便除錯專案啟動不了的問題。
更多引數細節:
-XDebug 啟用除錯。
-Xnoagent 禁用預設sun.tools.debug偵錯程式。
-Djava.compiler=NONE 禁止 JIT 編譯器的載入。
-Xrunjdwp 載入JDWP的JPDA參考執行例項。
transport 用於在除錯程式和 VM 使用的程序之間通訊。
dt_socket 套接字傳輸。
dt_shmem 共享記憶體傳輸,僅限於 Windows。
server=y/n VM 是否需要作為除錯伺服器執行。
address=3999 除錯伺服器的埠號,客戶端用來連線伺服器的埠號。
suspend=y/n 是否在除錯客戶端建立連線之後啟動 VM 。