線上Bug無法復現怎麼辦?老司機教你一招,SpringBoot遠程調試不用愁!

前言

  • 在部署線上項目時,相信大家都會遇到一個問題,線上的 Bug 但是在本地不會復現,多麼無奈。
  • 此時最常用的就是取到前端傳遞的數據用介面測試工具測試,比如 POSTMAN,複雜不,難受不?
  • 今天陳某教你一招,讓你輕鬆調試線上的 Bug。文章目錄如下:

什麼是 JPDA?

  • JPDA(Java Platform Debugger Architecture),即 Java 平台調試體系,具體結構圖如下圖所示。

  • 其中實現調試功能的主要協議是JDWP協議,在 Java SE 5 以前版本,JVM 端的實現介面是 JVMPI(Java Virtual Machine Profiler Interface),而在 Java SE 5 及以後版本,使用 JVMTI(Java Virtual Machine Tool Interface) 來替代 JVMPI。

  • 因此,如果使用 Java SE 5 之前版本,使用調試功能的命令為:

java -Xdebug -Xrunjdwp:...
  • Java SE 5 及之後版本,使用調試功能的命令為:
java -agentlib:jdwp=...

調試命令

  • 現在開發中最常見的一條遠程調試的的命令如下:
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9091 -jar xxx.jar

參數說明

  • 基於前面的調試命令,我們來分析一下基本的參數代表什麼意思。

transport

  • 指定運行的被調試應用和調試者之間的通訊協議,它由幾個可選值:
    1. dt_socket:主要的方式,採用socket方式連接。
    2. dt_shmem:採用共享記憶體方式連接,僅支援 Windows 平台。

server

  • 指定當前應用作為調試服務端還是客戶端,默認為n
  • 如果你想將當前應用作為被調試應用,設置該值為 y,如果你想將當前應用作為客戶端,作為調試的發起者,設置該值為n

suspend

  • 當前應用啟動後,是否阻塞應用直到被連接,默認值為 y
  • 在大部分的應用場景,這個值為 n,即不需要應用阻塞等待連接。一個可能為 y的應用場景是,你的程式在啟動時出現了一個故障,為了調試,必須等到調試方連接上來後程式再啟動。

address

  • 暴露的調試連接埠,默認值為 8000
  • 此埠一定不能與項目埠重複,且必須是伺服器開放的埠。

onthrow

  • 當程式拋出設定異常時,中斷調試。

onuncaught

  • 當程式拋出未捕獲異常時,是否中斷調試,默認值為 n。

launch

  • 當調試中斷時,執行的程式。

timeout

  • 該參數限定為java -agentlib:jdwp=…可用,單位為毫秒ms
  • suspend = y 時,該值表示等待連接的超時;當 suspend = n 時,該值表示連接後的使用超時。

參考命令

  1. -agentlib:jdwp=transport=dt_socket,server=y,address=8000:以 Socket 方式監聽 8000 埠,程式啟動阻塞(suspend 的默認值為 y)直到被連接。

  2. -agentlib:jdwp=transport=dt_socket,server=y,address=localhost:8000,timeout=5000:以 Socket 方式監聽 8000 埠,當程式啟動後 5 秒無調試者連接的話終止,程式啟動阻塞(suspend 的默認值為 y)直到被連接。

  3. -agentlib:jdwp=transport=dt_shmem,server=y,suspend=n:選擇可用的共享記憶體連接地址並使用 stdout 列印,程式啟動不阻塞。

  4. -agentlib:jdwp=transport=dt_socket,address=myhost:8000:以 socket 方式連接到 myhost:8000上的調試程式,在連接成功前啟動阻塞。

  5. -agentlib:jdwp=transport=dt_socket,server=y,address=8000,onthrow=java.io.IOException,launch=/usr/local/bin/debugstub:以 Socket 方式監聽 8000 埠,程式啟動阻塞(suspend 的默認值為 y)直到被連接。當拋出 IOException 時中斷調試,轉而執行 usr/local/bin/debugstub程式。

IDEA 遠程調試示例

  • 首先打包 SpringBoot 項目,在伺服器上運行,執行以下命令:
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9190 -jar debug-demo.jar
  • 出現下圖的介面,表示運行成功:

  • 然後在 IDEA 中,點擊 Edit Configurations,在彈框中點擊 + 號,然後選擇Remote

  • 填寫伺服器的地址,點擊 OK 即可。

  • 配置完畢後,DEBUG 調試運行即可。

  • 配置完畢後點擊保存即可,因為我配置的 suspend=n,因此服務端程式無需阻塞等待我們的連接。我們點擊 IDEA 調試按鈕,當我訪問某一介面時,能夠正常調試。

小福利

  • 作者為大家準備了接近 10M 的面試題,涵蓋後端各個技術維度,老規矩,公眾號內回復關鍵詞JAVA面試題即可免費獲取。
  • 關注微信公眾號回復關鍵詞: