IDEA如何远程调试

515 阅读4分钟

一、什么是远程调试

当我们的代码在线上/测试环境运行出现异常需要进行问题定位时

传统做法是:查看异常日志,根据日志定位到出错代码,然后再根据相关参数及异常信息进行推断。

但是很多异常问题需要更细致的进行debug才能够更精准的去定位和解决,这种情况下,我们希望能够像在本地调试一样去debug线上/测试环境的代码,这样可以大大提升bug修复的效率。IDEA 远程调试为我们提供了解决方案,像运行本地代码一样调试远程主机上的程序,以排查远程程序的BUG或代码执行流程。

二、远程DeBug调试原理

在本地远程调试服务器端的代码原理:本地和服务器端建立一个socket连接监听,当客户端访问服务器的时候,服务器端会先去问本地idea有没有断点,如果有会停在当前断点,如果没有就返回给客户端。

三、如何进行idea远程调试

1、主动连接调试

1.1 远程服务中先开启Debug服务

1.1.1 对于 SpringBoot (jar包)

命令行添加选项,并重启,注意新参数必须在 -jar 之前

java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 -jar springboottest.jar
1.1.2 对应Tomcat(war包)

启动脚本中添加选项,并重启:

## sudo vim $CATALINA_HOME/bin/catalina.sh
JAVA_OPTS="$JAVA_OPTS -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005" 

1.2 IDEA 中指定 Debug 服务器

image.png

  • 点击主窗口菜单 Run / Edit Configurations,打开Run/Debug Configurations窗口;
  • 点击工具栏上的+按钮,下拉菜单中选择Remote;
  • 设置 Host 为远程服务器的域名或IP,保持 Port=5005 无需调整;
  • Use module classpath配置为程序模块名称;
  • Command line arguments for remote JVM配置:配置Debug远程服务的命令行启动参数,形如 -Xdebug -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005,参数说明如下:
  • -Xdebug:JVM在DEBUG模式下工作;
  • -Xrunjdwp:JVM使用(java debug wire protocol)来运行调试环境;
  • transport:监听Socket端口连接方式,常用的dt_socket表示使用socket连接;
  • server:=y表示当前是调试服务端,=n表示当前是调试客户端;
  • suspend:=n表示启动时不中断(如果启动时中断,一般用于调试启动不了的问题);
  • address:表示本地监听的地址和端口。

1.3 远程服务器防火墙端口放行

如果调试服务器与远程服务器网络不相通则需要开放端口

### sudo vim /etc.sysconfig/iptables
-A INPUT -m state --state NEW -m tcp --dport 5005 -j ACCEPT
### 重启生效: sudo systemctl restart iptables

2、被动连接调试

首先需要IDEA配置监听,如主动连接调试的IDEA配置图片,Debugger mode选择:Listen to remote JVM,配置本地监听端口,比如默认5005。点击Debug开始等待远程连接调试。

2.1 对于 Tomcat

配置远程服务启动脚本:

## sudo vim $CATALINA_HOME/bin/catalina.sh
JAVA_OPTS="$JAVA_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,suspend=y,address=127.0.0.1:5005" 

2.2 对于SpirngBoot

参数含义和主动连接调试一样,只是这里suspend=y表示启动时就中断,需要连接本地IDE调试启动。address=ip:port,ip需要修改为本地的对外IP。 这样远程项目启动时就连接到本地,方便调试项目启动不了的问题。

java -Xdebug -Xrunjdwp:transport=dt_socket,suspend=y,address=127.0.0.1:5005 -jar springboottest.jar

四、注意事项有什么

1、停在本地的断点,关闭程序后是否会继续往下执行?

会继续往下执行

2、本地代码和远程代码不一致怎么办?

如果本地代码和远程代码不一致,是根据服务器端文件的行号来打的断点。而不是本地的Java代码 所以远程调试,一定得保证本地代码和远程代码一致,不然定位问题不准

3、远程调试代码,所有的日志是在远程打印,不会在本地控制台打印

4、远程调试某个接口,这时其他用户的访问这个接口会卡住

尽量在测试环境使用,不要在生产环境上使用。生产环境一般使用Arthas

5、远程调试可以调试Jar包,也可以调试war包