详解JAVA远程debug
目录
1.什么是远程debug?
远程debug,也就是可以在本地debug远端部署的程序,这对于定位远端环境中的问题非常有用,之所以我们说是远端环境,而不说是对定位生产环境中的bug很有用,是因为远程调试通常在开发和测试阶段使用,而不建议在生产环境中使用,因为可能会对性能产生影响。当然,在没有办法的时候使用远程debug,是最高效的定位生产问题的手段之一。
远程debug可以理解为一种JVM规范,当然其不是单独的一个规范,它是属于JDWP(Java Debug Wire Protocol)协议中的一部分,该协议定义了 Java 虚拟机(JVM)与调试器之间的交互方式。通过 JDWP,开发者可以在开发工具中设置断点、查看变量、执行代码等操作,以便对运行中的 Java 程序进行调试。说直白点就是遵循了该协议的JVM,就支持debug,也支持远程debug。
2.远程debug普通JAVA程序
2.1.环境
JDK:1.8
编译器:IDEA
2.2.测试程序
这里我们写了很简单一个测试程序,每1秒,i自加1,然后将其打包成jar包
public static void main(String[] args) throws InterruptedException {
int i=0;
while (true){
Thread.sleep(1000);
i++;
}
}
我估计很多同学一下会忘了这么在IDEA中将普通java se程序如何打包成jar了,这里贴心一点,给出打包方法,用打包jar包的maven插件,指定好main入口,然后install即可:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifest>
<mainClass>com.eryi.Test</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
2.3.程序启动指令
要远程debug,首先在程序启动时就要用参数开启远程debug,完成参数指令如下:
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=<host>:<port>
-
transport
:指定调试信息传输的方式,一般使用dt_socket
。 -
server
:指定是否为调试服务端,使用y
表示是。 -
suspend
:指定是否在启动时暂停,使用n
表示不暂停。 -
address
:指定调试监听的主机和端口,也就是通过该端口来进行远程debug的。
以我们上面的程序为例,完成的启动命令为:
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=127.0.0.1:5005 -jar test-1.0-SNAPSHOT.jar
启动成功会显示正在监听debug的端口:
2.4.编译器配置
我们想要在IDEA中远程debug,需要进行配置:
add configurations
add new configuration—>remote
配置:
开始debug:
可以看到程序进入了断点。
3.远程debug JAVA Web程序
tomcat作为常用的web server为了方便使用,自然也支持了远程debug的功能。普通java程序是用java -jar启动,tomcat是用启动脚本启动,启动脚本里记录的就是tomcat启动要执行的所有命令,远程debug也写在里面。
Windows环境下修改start.sh,在第一行加上以下命令:
export CATALINA_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,address=<host>:<port>,server=y,suspend=n"
Linux环境下修改start.bat,在第一行加上以下命令:
set "CATALINA_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,address=<host>:<port>,server=y,suspend=n"
4.远程debug spring boot程序
spring boot项目作为一个jar,是可以用java -jar然后跟参数这种启动普通Java程序debug的方式来进行debug的,除此之外,spring boot还提供了一个更方便的远程debug的方式,就是将参数配置在spring boot的打包插件中。
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<jvmArguments>-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=<host>:<port></jvmArguments>
</configuration>
</plugin>
</plugins>
</build>