文章目录

  • 为什么需要这么做?
  • 为什么可以进行远程调试,背后的原理是什么?
  • 远程调试原理
  • Java调试器架构
  • Tomcat 服务器配置方式
  • Jetty 服务器配置方式
  • SpringBoot项目配置方式
  • 配置参数拓展
  • 注:服务器代码最好和本地调试端代码保持一致


为什么需要这么做?

  • 解决 在我本地是好的啊 这个世界性难题~
  • 测试环境碰到问题,直接连上debug,不用再测试本地,再查看测试环境日志
  • 遇到一些诡异的问题,日志是看不出端倪的
  • 调试一些只能在测试环境执行的流程,如:调用微信/支付宝付款
  • 只能进行调试,修改代码并不会不起作用。还有,代码一定要保持一致 !!!!

通俗来讲

  • 当我们的项目部署到远程的服务器的时候,出错了只能苦逼的打印日志来查看错误信息。
  • 远程调试就作用就是你可以在本地进行对你的项目进行调试,很实用有没有。就是说你远程的服务器发布一个项目,发布的时候你需要带一些参数,然后你本地你可以在idea中配一下远程服务器的ip和端口号,然后在本地项目打debug就可以操控你服务器的项目了。

远程调试,特别是当你在本地开发的时候,你需要调试服务器上的程序时,远程调试就显得非常有用。

JAVA 支持调试功能,本身提供了一个简单的调试工具JDB,支持设置断点及线程级的调试同时,不同的JVM通过接口的协议联系,本地的Java文件在远程JVM建立联系和通信

本人的IDAEA版本为 2018.3.x,tomcat版本为8.5.x

为什么可以进行远程调试,背后的原理是什么?

首先,了解下的Java程序的执行过程- 分为以下几个步骤:
Java的文件—>编译生成的类文件(class文件)—>JVM加载类文件—>JVM运行类字节码文件—>JVM翻译器翻译成各个机器认识的不同的机器码。

远程调试原理

众所周知,Java 程序是运行在Java 虚拟机(JVM )上的,具有良好跨平台性,是因为Java程序统一以字节码的形式在JVM中运行,不同平台的虚拟机都统一使用这种相同的程序存储格式。因为都是类字节码文件,只要本地代码和远程服务器上的类文件相同,两个JVM通过调试协议进行通信(例如通过插座在同一个端口进行通信),另外需要注意的时,被调试的服务器需要开启调试模式,服务器端的代码和本地代码必须保持一致,则会造成断点无法进入的问题。

Java调试器架构

idea 获取远程email从哪里读_调试


这个架构其实质还是JVM,只要确保本地的的的Java的源代码与目标应用程序一致,本地的Java的的的的源码就可以用插座连接到远端的JVM,进而执行调试。因此,在这种插座连接模式(下文介绍)下,本地只需要有源码,本地的的的的Java的应用程序根本不用启动。

Tomcat 服务器配置方式

  • 以 Linux 环境为例
  • Tomcat 安装在: /usr/program/tomcat7
  • Tomcat 的执行程序:/usr/program/tomcat7/bin/catalina.sh
  • 编辑 Tomcat 执行程序: vim /usr/program/tomcat7/bin/catalina.sh
  • 查找Tomcat的debug端口:/JPDA_ADDRESS=
  1. 配置服务器启动参数
  • 默认的debug端口是8000,我这里是配成了5005
  • 在bin目录下执行命令 sh catalina.sh jpda start,可以启动tomcat并开启远程调试的端口

其实官方教程是在catalina.sh/catalina.bat文件的开头加上

export JAVA_OPTS='-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005' (任意端口只要不占用),然后在remote配置面配置远程监听参数, 启动startup.sh/startup.bat即可

如果不想让其他同事也是以debug模式启动,可以用我这种模式

  1. 打开idea,配置 remote
    点击下图红框中的”run”按钮,在下拉菜单中点击“Edit Configurations…“
  2. idea 获取远程email从哪里读_调试_02

  3. 点击Edit Configurations,进入如下界面:
  4. idea 获取远程email从哪里读_idea 获取远程email从哪里读_03

  5. 配置连接参数
  6. idea 获取远程email从哪里读_springBoot_04

5.启动远程debug

设置完毕后点击下面的“ok“,回到主窗口后,点击下图红框中的下拉菜单,选中我们刚才新建的debug配置项,再点击小虫按钮,就能连接到tomcat的debug端口了:

idea 获取远程email从哪里读_调试_05


如果看到下图则代表成功了

idea 获取远程email从哪里读_调试_06


启动成功后,服务器catalina.out会出现, 表示调试服务端(被调试远程运行的机器)启动一个端口等待我们(调试客户端)去连接,此种模式下,是我们(调试客户端)去监听一个端口,当调试服务端准备好了,就会进行连接。

idea 获取远程email从哪里读_调试_07

Jetty 服务器配置方式

  1. jetty服务器启动参数配置
  • 以 Linux 环境为例
  • Tomcat 安装在 /usr/program/tomcat7, jetty 不像Tomcat那样需要安装,只要有jetty的jar包就可以启动我们想要启动的应用
  • 在启动应用的时候加入
    agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
  • 就像这样:
    java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -jar {your jetty path} {your port} --path {your war} 1>/dev/null 2>&1 &
  1. 配置 remote
    点击下图红框中的”run”按钮,在下拉菜单中点击“Edit Configurations…“

    在弹出的菜单中点击“+“,再点击“Remote“:
  2. 配置连接参数
    如下图,修改Port(catalina.out配置的端口)框中的数字为之前设置的Tomcat-debug端口号(默认8000),如果tomcat部署在其他机器上,请在Host输入框中填入tomcat所在机器的ip:
  3. 启动远程debug
    设置完毕后点击下面的“ok“,回到主窗口后,点击下图红框中的下拉菜单,选中我们刚才新建的debug配置项,再点击小虫按钮,就能连接到tomcat的debug端口了:

    如果看到下图则代表成功了

SpringBoot项目配置方式

  1. 配置pom.xml(实际上不加也可以)
<plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <jvmArguments>
                        -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005
                    </jvmArguments>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
</plugins>

注意address=5005是指调试服务端暴露的监听端口。你idea连的就是这个端口。任意指定

  1. 把SpringBoot项目打成jar包启动
    注意:这个address号一定要和maven的一致。因为你不写的话,jvm会自动创建一个端口 启动命令:
java -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=5005,suspend=n -jar xxxx.jar
  1. SpringBoot项目启动后配置连接调试服务端

启动成功的画面

idea 获取远程email从哪里读_idea 获取远程email从哪里读_08

配置参数拓展

idea 获取远程email从哪里读_jetty_09

  • 标注 1:运行远程 JVM 的命令行参数;
  • 标注 2:传输方式,默认为Socket
  • 标注 3:调试模式,默认为Attach
  • 标注 4:服务器 IP 地址,默认为localhost,需要修改为目标服务器的真实 IP 地址
  • 标注 5:服务器端口号,默认为5005,需要修改为目标服务器的真实端口号
  • 标注 6:搜索资源是使用的环境变量,默认为,即整个项目。

如上图所示,其中 标注 2标注 3又分别有两种分类,
标注 2: 传输方式,默认为Socket;

  • Socket:macOS 及 Linux 系统使用此种传输方式;
  • Shared memory: Windows 系统使用此种传输方式。

标注 3:调试模式,默认为Attach;

  • Attach:此种模式下,调试服务端(被调试远程运行的机器)启动一个端口等待我们(调试客户端)去连接;
  • Listen: 此种模式下,是我们(调试客户端)去监听一个端口,当调试服务端准备好了,就会进行连接。
    然后,复制 标注 1,即 IntelliJ IDEA 自动生产的命令行参数,然后导入到 Tomcat 的配置文件中。

如果是 Linux系统,则导入语句为:

export JAVA_OPTS='-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8001'

如果是 Windows 系统,则导入语句为:

set JAVA_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8001

注:address为自定义的端口号

两者的区别在于:导入语句的关键字不同以及有无引号

  1. Linux系统的导入关键字为exportWindows 为set
  2. Linux 的导入值需要用单引号”括起来,而 Windows 则不用。
  3. Linux系统修改 服务器端Tomcat 的 bin 目录下的catalina.sh文件,如果是 Windows 系统则修改catalina.bat文件,将上述的导入语句添加到此文件中即可:

注:服务器代码最好和本地调试端代码保持一致