轉自:https://www.cnblogs.com/zhangzhonghui/articles/12185863.html
參考:https://www.cnblogs.com/sunweiye/p/12003733.html
配置步驟如下:
- 打開 IDEA 中的 Run/Debug Configurations
- 選擇頂部的 “+” 按鈕,找到選項中的 Remote
- 進行遠程調試配置
- ①:隨便對當前服務取個名稱(非必須,可使用默認的)
- ②:Host:遠程服務的 IP(具體部署項目的服務器IP),
- ③:Port:遠程服務的端口(切記不要重復)若將項目部署到 Linux 需要 使用 lsof -i :端口 查看一下端口是否別占用,這一步重要。
- ④:最后 點擊 Apply 進行保存(Apply 與 OK 的區別 ,一個是保存並運用,Ok 只是保存)。
對於為什么這里要配置重新配置ip 和端口 我一開始也不知道,后面慢慢又想通了,首先是兩個服務,要進行通信不配置“鏈接”,怎么去實時監控呢?是不是這個道理。
- 啟動服務(Linux 部署項目)
- 核心參數:-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=端口(上一步中③中配置的端口)。
-
遠程調試啟動配置:nohup java -jar -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=端口 *.jar &
- 普通的啟動配置:nohup java -jar *.jar & 。
- 本地啟動遠程調試
- 和啟動 Springboot 項目 類似
- 啟動日志,並不是很多
- 進行測試(這里需要注意的是,本地代碼和服務器上的代碼需要保持一致,否則斷點失敗)。
- 在本地代碼上 加入斷點
- 為了方便,我使用 測試環境上的 swagger 進行測試
- 測試成功,成功進入本地代碼的斷點測試中。
為什么可以進行遠程調試,背后的原理是什么
首先,了解下的Java程序的執行過程- 分為以下幾個步驟:Java的文件 - - 編譯生成的類文件(class文件) - - JVM加載類文件 - - JVM運行類字節碼文件 - - JVM翻譯器翻譯成各個機器認識的不同的機器碼。
遠程調試原理
眾所周知,Java 程序是運行在Java 虛擬機(JVM )上的,具有良好跨平台性,是因為Java程序統一以字節碼的形式在JVM中運行,不同平台的虛擬機都統一使用這種相同的程序存儲格式。因為都是類字節碼文件,只要本地代碼和遠程服務器上的類文件相同,兩個JVM通過調試協議進行通信(例如通過插座在同一個端口進行通信),另外需要注意的時,被調試的服務器需要開啟調試模式,服務器端的代碼和本地代碼必須保持一致,則會造成斷點無法進入的問題。
<code>Java</code>的調試器架構
1.這個架構其實質還是JVM,只要確保本地的Java的源代碼與目標應用程序一致,本地的Java的的的的源碼就可以用插座連接到遠端的JVM,進而執行調試。因此,在這種插座連接模式(下文介紹)下,本地只需要有源碼,本地的Java的應用程序根本不用啟動。
傳輸方式,默認為Socket ;
套接字:MACOS,Linux的系統使用此種傳輸方式;
共享內存:WINDOWS系統使用此種傳輸方式。
調試模式:默認為Attach ;
Attach :此種模式下,調試服務端(被調試遠程運行的機器)啟動一個端口等待我們(調試客戶端)去連接;
Socket :此種模式下,是我們(調試客戶端)去監聽一個端口,當調試服務端准備好了,就會進行連接。
配置屬性說明補充
文本:
CATALINA_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8089"
2.各參數解釋:
-Xdebug:通知JVM工作在調試模式下
-Xrunjdwp:通知JVM使用(java debug wire protocol)來運行調試環境。參數同時有一系列的調試選項:
<code>session</code>:指定了調試數據的傳送方式,dt_socket是指用SOCKET模式,另外dt_shmem指用共享內存方式,其中dt_shmem只適用於窗口平台.server 參數是指是否支持在服務器模式的虛擬機中。
onthrow:指明當產生該類型的異常時,JVM就會中斷下來,進行調式該參數任選。
<code>release</code>:指明當JVM被中斷下來時,執行的可執行程序該參數可選
<code>suspend</code><:指明:是否在調試客戶端建立起來后,再執行 JVM。
onuncaught(= y或n)指明出現未捕獲的異常后,是否中斷JVM的執行