SpringBoot 远程DeBug

远程debug调试java代码

日常环境和预发环境遇到问题时,可以用远程调试的方法本地打断点,在本地调试。生产环境由于网络隔离和系统稳定性考虑,不能进行远程代码调试。也就是说,你本地运行没问题啊,为啥放服务器上就有问题看了,这时候应该怎么办呢?

整体过程是通过修改远程服务JAVA_OPTS参数,然后本地通过Eclipse或IDEA等工具调试。

基本理论

Java远程调试的原理是两个VM之间通过debug协议进行通信,然后以达到远程调试的目的。两者之间可以通过socket进行通信。首先被debug程序的虚拟机在启动时要开启debug模式,启动debug监听程序。jdwp是Java Debug Wire Protocol的缩写。

命令如下

java -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=8000,suspend=n -jar demo.jar

这是jdk1.7版本之前的方法,1.7之后可以这样用:

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

差不多就是这样一个原理

参数说明

transport

指定运行的被调试应用和调试者之间的通信协议,它由几个可选值:

  • dt_socket:主要的方式,采用 socket 方式连接
  • dt_shmem:采用共享内存方式连接,仅支持 Windows 平台(暂未验证)

server

当前应用作为调试服务端还是客户端,默认为 n

如果你想将当前应用作为被调试应用,设置该值为 y;如果你想将当前应用作为客户端,作为调试的发起者,设置该值为 n

suspend

当前应用启动后,是否阻塞应用直到被连接,默认值为 y

suspend=n表示启动时不需要应用阻塞等待连接,表示当前是调试服务端

suspend=y表示当前是调试客户端 ,那么当前的VM就是suspend直到有debug client连接进来才开始执行程序,方便调试项目启动不了的问题。

address

暴露的调试连接端口,默认值为 8000

onthrow

当程序抛出设定异常时,中断调试。

onuncaught

当程序抛出未捕获异常时,是否中断调试,默认值为 n

launch

当调试中断时,执行的程序。

timeout

该参数限定为 java -agentlib:jdwp=… 可用,单位为毫秒ms。

当 suspend = y 时,该值表示等待连接的超时;当 suspend = n 时,该值表示连接后的使用超时。

参考实例

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

以 Socket 方式监听 8000 端口,程序启动阻塞(suspend的默认值为y)直到被连接。

-agentlib:jdwp=transport=dt_socket,server=y,address=localhost:8000,timeout=5000

以 Socket 方式监听 8000 端口,当程序启动后5秒无调试者连接的话终止,程序启动阻塞(suspend的默认值为y)直到被连接。

-agentlib:jdwp=transport=dt_shmem,server=y,suspend=n

选择可用的共享内存连接地址并使用 stdout 打印,程序启动不阻塞。

-agentlib:jdwp=transport=dt_socket,address=myhost:8000

以 socket 方式连接到 myhost:8000上的调试程序,在连接成功前启动阻塞。

-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 远程调试

先运行这个程序

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

这时候程序就会开一个8000 端口然后在idea中

Edit Configurations-> + -> Remote


设置后

Use module classpath 中设置你要 调试的代码 点击启动即可。