知識庫 / DevOps RSS 訂閱

調試 Spring 應用

DevOps,Spring
HongKong
4
01:34 PM · Dec 06 ,2025

1. 簡介

調試是編寫軟件最重要的工具之一。

在本教程中,我們將回顧如何調試 Spring 應用的一些方法。

我們還將演示 Spring Boot、傳統應用程序服務器和 IDE 如何簡化這一過程。

2. Java 調試參數

首先,讓我們看看 Java 默認提供什麼。

默認情況下,JVM 不啓用調試功能。 這是因為調試會增加 JVM 內部的額外開銷。 此外,對於公開可訪問的應用程序,調試也可能存在安全問題。

因此,調試應僅在開發期間進行,絕不應用於生產系統

在我們可以附加調試器之前,我們必須首先配置 JVM 以允許調試。 我們將通過為 JVM 設置命令行參數來完成此操作:

-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000

讓我們來分解一下這些值的含義:

-agentlib:jdwp

這啓用 JVM 內部的 Java Debug Wire Protocol (JDWP) 代理。 這是主要命令行參數,用於啓用調試。

transport=dt_socket

這使用網絡套接字進行調試連接。 其他選項包括 Unix 套接字和共享內存。

server=y

這偵聽傳入的調試器連接。 當設置為 n 時,進程將嘗試連接到調試器,而不是等待傳入連接。 當設置為 n 時,需要提供額外的參數。

suspend=n

這意味着在啓動時不要等待調試連接。 應用程序將正常啓動和運行,直到附加調試器。 當設置為 y 時,進程將在附加調試器之前不會啓動。

address=8000

這是 JVM 監聽傳入調試連接的網絡端口。

上述值是標準且適用於大多數用例和操作系統。 JPDA 連接指南 提供了更詳細的信息。

2.1. JDK9+ 綁定地址

在 JDK8 及以下版本中,將 address 屬性設置為端口號(如示例中所示 address=8000)意味着 JVM 會監聽所有可用的 IP 地址。因此,遠程連接是默認可用的。

此行為在 JDK9+ 版本中已發生改變,主要是出於安全考慮。目前,默認設置僅允許 localhost 連接。

這意味着,為了使遠程連接可用,我們需要在端口號前加上主機名,例如 address=myhost:8000,或者使用 asterisk 來監聽所有可用的 IP 地址,例如 address=*:8000。

3. Spring Boot 應用

有幾種方法 可以啓動 Spring Boot 應用。 最簡單的方法是從命令行使用 java 命令,並帶有 -jar 選項。

要啓用調試,我們只需使用 -D 選項添加 debug 參數:

java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000 -jar myapp.jar

使用 Maven,我們可以使用提供的 run 目標來啓動我們的應用程序,並啓用調試功能:

mvn spring-boot:run -Dspring-boot.run.jvmArguments="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000"

同樣,使用 Gradle 時,我們也可以使用 bootRun 任務。首先,我們需要更新 build.gradle 文件,以確保 Gradle 將命令行參數傳遞給 JVM:

bootRun {
   systemProperties = System.properties
}

現在我們可以執行 bootRun 任務:

gradle bootRun -Dagentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000

4. 應用服務器

儘管近年來 Spring Boot 越來越受歡迎,但在現代軟件架構中,傳統的應用服務器仍然非常普遍。 在本節中,我們將探討如何為一些流行的應用服務器啓用調試。

大多數應用服務器都提供一個啓動和停止應用程序的腳本。 啓用調試通常只需在腳本中添加額外的參數,或者設置額外的環境變量。

4.1. Tomcat

Tomcat 的啓動腳本名為 <em >catalina.sh</em > (catalina.bat 在 Windows 上)。要以調試模式啓動 Tomcat 服務器,可以將 <em >jpda</em > 添加到參數的前面:

catalina.sh jpda start

默認調試參數將使用一個監聽在 8000 端口的網絡套接字,且 suspend=n。可以通過設置以下一個或多個環境變量來更改這些參數:JPDA_TRANSPORT, JPDA_ADDRESS, 和 JPDA_SUSPEND.

我們還可以通過設置 JPDA_OPTS 完全控制調試參數。當此變量被設置時,它將優先於其他 JPDA 變量,因此它必須是 JVM 的完整調試參數。

4.2. Wildfly

The startup script for Wildfly is <em >stand-alone.sh</em>. To start a Wildfly server with debug enabled, we can add <em >–debug</em>.

The default debug mode uses a network listener on port 8787 with <em >suspend=n</em>. We can override the port by specifying it after the <em >–debug</em> argument.

For more control over the debug argument, we can just add the complete debug arguments to the <em >JAVA_OPTS</em> environment variable.

4.3. Weblogic

啓動 Weblogic 腳本為 startWeblogic.sh。要啓動帶有調試啓用的 Weblogic 服務器,可以將環境變量 debugFlag 設置為 true

默認調試模式使用端口 8453 的網絡監聽器,且 suspend=n。可以通過設置環境變量 DEBUG_PORT 來覆蓋端口。

要對調試參數進行更精細的控制,可以將完整的調試參數添加到 JAVA_OPTIONS 環境變量中。

最新版本的 Weblogic 還提供 Maven 插件來啓動和停止服務器。該插件將尊重啓動腳本中使用的相同環境變量

<h3><strong>4.4. Glassfish</strong></h3><p>啓動 Glassfish 腳本是 <em >asadmin</em>。要以調試模式啓動 Glassfish 服務器,我們需要使用 <em >–debug</em>:</p>
asadmin start-domain --debug

默認調試模式使用一個在端口 9009 上運行的網絡監聽器,並使用 suspend=n

4.5. Jetty

Jetty 應用服務器不自帶啓動腳本。相反,Jetty 服務器使用 java 命令啓動。

因此,啓用調試非常簡單,只需添加標準的 JVM 命令行參數即可。

5. 從 IDE 進行調試

現在我們已經瞭解瞭如何在各種應用程序類型中啓用調試,接下來讓我們看看如何連接調試器。

每個現代 IDE 均提供調試支持。這包括啓動具有調試功能的全新進程的能力,以及調試已運行進程的能力。

<h3><strong>5.1. IntelliJ</strong></h3><p><strong>IntelliJ</strong><strong> 對 Spring 和 Spring Boot 應用程序提供一流的支持。</strong>調試就像導航到帶有 <em>main</em> 方法的類,右鍵單擊三角形圖標,然後選擇“調試”:</p><img src="/file/story/attachments/image/l/c4c68984-dcd1-4de8-b61b-bcbbc6a209a1"><p><strong>對於 Spring Boot 應用程序,IntelliJ IDEA 提供了一個專用插件——Spring Debugger。</strong>該插件允許我們查看已加載的 Bean、實際屬性值和數據庫連接等,均在 IDE 中可見。它適用於從 2025.2 版本及更高版本的高端版 IDEA。</p><p>如果一個項目包含多個 Spring Boot 應用程序,IntelliJ 將提供 Run Dashboard 工具窗口。該窗口允許我們從一個地方調試多個 Spring Boot 應用程序:</p><img src="/file/story/attachments/image/l/4f0b9c75-76c4-459d-a89c-3fca2d307c3d"><p>對於使用 Tomcat 或其他 Web 服務器的應用程序,我們可以為調試創建自定義配置。在 <em>Run</em> &gt; <em>Edit Configurations</em> 下,有許多用於最受歡迎的應用程序服務器的模板:</p><img src="/file/story/attachments/image/l/18b86885-65e0-439f-a9a3-6d282f96cdf9"><p>最後,IntelliJ 使得連接到任何正在運行的進程並進行調試變得非常容易。 <strong as long as the application was started with the proper debug arguments</strong>,IntelliJ 可以在另一台主機上連接到它,即使它已啓動:</p><p>在 <em>Run/Debug Configurations</em> 屏幕上,<em>Remote</em> 模板將允許我們配置如何附加到已運行的應用程序:</p><img src="/file/story/attachments/image/l/7d140ce9-fe3e-41f9-b941-bbe3fc1151eb"><p>請注意,IntelliJ 只需要知道主機名和調試端口。為了方便起見,它會告訴我們應該在要調試的應用程序上使用的正確 JVM 命令行參數。</p>

5.2. Eclipse

使用 Eclipse 調試 Spring Boot 應用程序最快的方法是右鍵單擊主方法,從 Package ExplorerOutline 窗口中:

Eclipse 的默認安裝不支持 Spring 或 Spring Boot。但是,Eclipse Marketplace 中有一個 Spring Tools 插件,它提供了與 IntelliJ 類似的可比的 Spring 支持。

最重要的是,該插件提供了一個 Boot 面板,允許我們在單個位置管理多個 Spring Boot 應用程序:

該插件還提供了一個 Spring Boot 運行/調試配置,允許我們自定義單個 Spring Boot 應用程序的調試。 此自定義視圖可在與標準 Java Application 配置相同的地點訪問。

要調試正在運行的進程(無論本地還是遠程主機),我們可以使用 Remote Java Application 配置:

6. 使用 Docker 進行調試

在 Docker 容器內部調試 Spring 應用程序可能需要額外的配置。 如果容器在本地運行,且未使用宿主機網絡模式,則調試端口將無法從外部訪問。

在 Docker 中暴露調試端口有多種方法。

我們可以使用 –expose 選項與 docker run 命令結合使用:

docker run --expose 8000 mydockerimage

我們還可以將 EXPOSE 指令添加到 Dockerfile 中:

EXPOSE 8000

或者,如果使用 Docker Compose,我們可以將其添加到 YAML 中:

expose:
 - "8000"

7. 結論

在本文中,我們討論瞭如何為任何 Java 應用程序啓用調試功能。

只需添加一個命令行參數,我們就可以輕鬆地調試任何 Java 應用程序。

我們還了解到,Maven、Gradle 以及大多數流行的 IDE 都具有專門的附加組件,可以更輕鬆地調試 Spring 和 Spring Boot 應用程序。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.