背景
有時候我們需要進行遠程的debug,本文研究如何進行遠程debug,以及使用 IDEA 遠程debug的過程中的細節。看完可以解決你的一些疑惑。
配置
遠程debug的服務,以springboot微服務為例(springcloud的應該差不多,我沒研究過)。首先,啟動springboot需要加上特定的參數。
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變得安全了,遠程調試只允許本地,如果要遠程,則需要在端口前配置*
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")
4、細節4:調試時其他人會不會卡???
public String test1() {
System.out.println("第一行");
System.out.println("第二行");
log.info("log 第一行");
log.info("log 第二行");
return "ok";
遠程調試的時候,打了斷點,停住后會不會導致頁面的請求卡住。
比如你使用遠程調試,別的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,但是又不能立即修復后繼續調試,只能修復后部署后繼續遠程調試
作者:石頭wang 來源:blog.csdn.net/w8y56f/article/ details/116493681
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.