java中的远程调试

Jan 23, 2019 • kael


前言

在开发过程中,我们经常遇到这样的情况:

  • 在开发环境中运行的时候没有出现问题,打包运行就有问题了
  • 在特定的场景下,生产环境运行发生异常,在开发环境则是正常的

这两种情况下,要调试定位问题非常困难,需要增加很多日志来协助定位,但是再无法判断bug发生的位置的情况下,日志也未必能帮助我们定位问题,这种情况下,我们就可以借助远程调试机制来定位问题。

JVM开启远程调试

要开启JVM的远程调试功能,只需要增加JVM启动参数即可:

对于JDK1.5及以上版本(到JDK8),使用如下启动参数:

$> -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=1044

参数说明如下:

  • transport=dt_socket:表示远程连接的方式,一般是socket,还有dt_shmem共享内存模式,一般建议使用socket模式
  • address=1044:表示socket监听的端口
  • suspend=n:表示是否等待客户端连接后才启动,n表示正常启动,y表示等待客户端连接后再启动,如果需要调试启动过程则设置为y

注意:不同的JDK版本,开启远程调试的参数不一样,目前最广泛使用的版本是JDK5-8,其他版本请参考附录

maven开启远程调试

如果使用maven运行单元测试或者启动应用,想要开启远程调试可以增加如下参数:

-Dmaven.surefire.debug

如:

$>  mvn clean test -Dmaven.surefire.debug

启动后maven运行到测试开始前会阻塞,等待远程调试连接后继续:


-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Listening for transport dt_socket at address: 5005

此时只要使用调试工具连上即可进行远程调试。

idea连接远程调试

Intellij Idea对远程调试的支持非常好,可以支持本地连接调试和远程连接调试。

本地连接调试

本地连接调试,在顶部菜单中打开,Run -> Attach To Process...,如下图:

打开之后,会列出本机中目前允许远程调试的进程:

此时只要选择自己想要远程调试的进程即可。

远程连接调试

远程连接调试,需要配置远程连接,在顶部菜单中打开Run -> Edit Configurations...,如下图:

打开后,点击右上角的+号,增加一个Remote的启动配置:

填写好对应的配置参数,点击确定保存即可:

保存后,运行远程调试,即可连接远程运行的服务进行调试了。

附录

版本 命令
JDK3及以下 -Xnoagent -Djava.compiler=NONE -Xdebug
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=1044
JDK4 -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=1044
JDK5~8 -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=1044
JDK9以上 -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:1044