远程调试
远程调试与 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 SE 5
之后的版本,则之前的就忽略了。
日常开发中最常见的开启远程调试的命令如下:
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=10086 -jar xxx.jar
前面的java -agentlib:jdwp=
是基础命令,后面的跟着的一串命令则是可选的参数,具体意思为:
transport
:指定运行的被调试应用和调试者之间的通信协议,有如下可选值:dt_socket
: 采用socket
方式连接(常用)dt_shmem
:采用共享内存的方式连接,支持有限,仅仅支持 windows 平台
server
:指定当前应用是否作为服务端,默认值为n
,即作为客户端。- 如果你想将当前应用作为被调试应用,设置该值为
y
; - 如果你想将当前应用作为客户端,即调试的发起者,设置该值为
n
。
- 如果你想将当前应用作为被调试应用,设置该值为
suspend
:当前应用启动后,是否阻塞应用直到被连接,默认值为y
(阻塞)。- 大部分情况下这个值应该为
n
,即不需要阻塞等待连接。 - 一个可能为
y
的应用场景是,你的程序在启动时出现了一个故障,为了调试,必须等到调试方连接上来后程序再启动。
- 大部分情况下这个值应该为
address
:对外暴露的端口,默认值是8000
注意:此端口不能和项目同一个端口,且需要未被占用以及对外开放。
onthrow
:这个参数的意思是当程序抛出指定异常时,则中断调试。onuncaught
:当程序抛出未捕获异常时,是否中断调试,默认值为n
。launch
:当调试中断时,执行的程序。timeout
:超时时间,单位ms
(毫秒)。- 当
suspend=y
时,该值表示等待连接的超时; - 当
suspend=n
时,该值表示连接后的使用超时。
- 当
命令示例
下面列举几个常用的参考命令,这样更加方便理解。
以
Socket
方式监听8000
端口,程序启动阻塞(suspend
的默认值为y
)直到被连接,命令如下:-agentlib:jdwp=transport=dt_socket,server=y,address=8000
以
Socket
方式监听8000
端口,当程序启动后5
秒无调试者连接的话终止,程序启动阻塞(suspend
的默认值为y
)直到被连接:-agentlib:jdwp=transport=dt_socket,server=y,address=localhost:8000,timeout=5000
选择可用的共享内存连接地址并使用
stdout
打印,程序启动不阻塞:-agentlib:jdwp=transport=dt_shmem,server=y,suspend=n
以
socket
方式连接到myhost:8000
上的调试程序,在连接成功前启动阻塞:-agentlib:jdwp=transport=dt_socket,address=myhost:8000
以
Socket
方式监听8000
端口,程序启动阻塞(suspend
的默认值为y
)直到被连接。当抛出IOException
时中断调试,转而执行usr/local/bin/debugstub
程序:-agentlib:jdwp=transport=dt_socket,server=y,address=8000,onthrow=java.io.IOException,launch=/usr/local/bin/debugstub
IDEA 如何开启远程调试?
服务器上
首先的将打包后的Spring Boot
项目在服务器上运行,执行如下命令(各种参数根据实际情况自己配置):
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9193 -jar debug-demo.jar
项目启动成功后,进行本地配置。
本地
- 在 IDEA 中点击
Edit Configurations
,在弹框中点击+
号,然后选择Remote
。 - 然后填写服务器的 IP 地址及端口,点击
OK
进行创建。 - 以 DEBUG 模式启动。
这里是一个创建好的示例:
