![](https://img2023.cnblogs.com/other/1218593/202308/1218593-20230822164212978-1679813836.png) ### 背景 有時候我們需要進行遠程的debug,本文研究如何進行遠程debug,以及使用 IDEA 遠程de ...
背景
有時候我們需要進行遠程的debug,本文研究如何進行遠程debug,以及使用 IDEA 遠程debug的過程中的細節。看完可以解決你的一些疑惑。
配置
遠程debug的服務,以springboot微服務為例(springcloud的應該差不多,我沒研究過)。首先,啟動springboot需要加上特定的參數。
推薦一個開源免費的 Spring Boot 實戰項目:
1、IDEA設置
高低版本的 IDEA 的設置可能界面有點不一樣,我用2020.1.1的。大致上差不多,自行摸索。
IDEA打開遠程啟動的springboot應用程式所對應的
1.選擇 Edit Configuration
2.如圖,點擊加號,選擇Remote
3.配置,詳細步驟見圖
註意:註意埠別被占用。後續這個埠是用來跟遠程的java進程通信的。
可以註意到:切換不同的jdk版本,生成的腳本不一樣
選擇 jdk1.4,則為
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=50055
這就是你為什麼搜其他博客,會有這種配置的原因,其實這個配置也是可行的。但更準確應該按照下麵jdk5-8的配置
選擇 jdk 5-8,則為
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=50055
選擇 jdk9以上,則為
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:50055
據說因為jdk9變得安全了,遠程調試只允許本地,如果要遠程,則需要在埠前配置*
。
另外,關註公眾號Java技術棧,在後臺回覆關鍵字:IDEA,閱讀我寫的大量 IDEA 教程。
2、啟動腳本改造
使用第一步得到的 Command line arguments for remote JVM
即可,即-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=50055
改造後的啟動腳本如下
nohup java \
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=50055 \
-jar remote-debug-0.0.1-SNAPSHOT.jar &
註意在windows中用 ^ 來進行換行,例如
java ^
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=50055 ^
-jar remote-debug-0.0.1-SNAPSHOT.jar
說明:
1、埠可隨意自己定,未被占用的都行,但是要和IDEA里的remote中設置的埠一致!其他參數照抄。詳細的參數解釋可以參照附錄或自己搜
2、remote-debug-0.0.1-SNAPSHOT.jar
改成給你自己的 jar 包名字
3、我給的腳本是後臺運行的,如不需要後臺運行,自行去掉 nohup
和 &
3、啟動springboot,啟動IDEA里的
IDEA 遠程調試的細節
1、細節1:停在本地斷點,關閉程式後會繼續執行嗎
如果遠程調試在自己的斷點處停下來了,此時關閉IDEA中的項目停止運行,則還會繼續運行執行完剩下的邏輯嗎?會的,這點比較不容易記住
以下麵的代碼為例,在第一行停住了。然後IDEA中停掉,發現停掉之後控制台還是列印了剩下的日誌。
2、細節2:jar包代碼和本地不一致會怎麼樣?
IDEA 里的代碼如果不和jar包的一致,會怎麼樣。
結論:要保證和遠程啟動的代碼一致。
否則你debug的時候的行數會對不上。報錯拋異常倒是不會。像這種還是能對得上行數的
比如你調試test1方法,test2方法在test1下麵,在test2裡加代碼,這樣並不影響test1中的行號,這種是可以在調試的時候準確反應行號的
3、細節3:日誌列印在哪裡?
日誌不會列印在IDEA的控制臺上。即System.out
以及 log.info
還是列印在遠程的。
@GetMapping("/test1")
public String test1() {
System.out.println("第一行");
System.out.println("第二行");
log.info("log 第一行");
log.info("log 第二行");
return "ok";
}
4、細節4:調試時其他人會不會卡住?
遠程調試的時候,打了斷點,停住後會不會導致頁面的請求卡住。
比如你使用遠程調試,別的QA在測試這個頁面,結果他們看到的結果是怎麼樣的?會卡住嗎?會的,已經實際遇到過這種情況了。
5、細節5:本地代碼修複bug遠程調用的時候
如果在遠程調試過程自己發現了bug,本地改好後重新啟動IDEA里的項目,再到頁面調用一次,能修複嗎?不能,運行的還是遠程部署的jar中的代碼
這個直接擊碎了遠程頁面點一點觸發本地代碼進行debug的夢想。如果可以的話那調試代碼就方便太多。
6、細節6:這個不算遠程調試的問題,是dropframe的問題,放在這裡一起講了
關於drop frame
的問題,如果drop frame
了重新進行調試,會不會插入2條記錄?
如圖 userMapper.insert(eo)
,本方法沒有使用 @Transactional
修飾,mapper方法執行過後事務會被立即提交,則庫表裡多了一行記錄,如果drop frame
後,再次進行調試,再次執行這代碼,於是又插入了一條記錄。
如果加上 @Transational
就不會有兩條記錄了,dropframe的時候事務沒被提交,再次執行該插入代碼也不會插入2條。
關於什麼是drop frame
7、細節7:跟上面一樣,是dropframe問題
如果把上述插入資料庫的邏輯,換成調用遠程的介面,在dropframe後,再次執行相同的代碼,會不會導致遠程介面被執行了2次?會的。
總結
好像感覺遠程調試的用處也不是那麼大,不能作為長期使用的調試工具。只能作為臨時調試的手段。
難點有幾個:
- 難保證本地代碼和遠程一致,而且你也很難判斷是否一致
- 通過遠程調試發現了bug,但是又不能立即修複後繼續調試,只能修複後部署後繼續遠程調試
版權聲明:本文為CSDN博主「石頭wang」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。原文鏈接:https://blog.csdn.net/w8y56f/article/details/116493681
近期熱文推薦:
1.1,000+ 道 Java面試題及答案整理(2022最新版)
4.別再寫滿屏的爆爆爆炸類了,試試裝飾器模式,這才是優雅的方式!!
覺得不錯,別忘了隨手點贊+轉發哦!