前言
最近,在做公司需求的时候,发生了一件事情,我在本地测试的时候,是正常的,但是部署到了测试环境的时候发现出现了一个意想不到的异常,没有办法查到问题出在哪里,后来针对这个,我同事告知我可以使用远程DEBUG的方式查问题
但我之前并没有研究过,不知道如何操作,因此针对它我进行了研究,最终实现了触发测试环境的按钮,使其触发的接口功能能够在本地进行debug
原理
远程Debug基于Java平台的JPDA架构,包含三个核心组件
[你的IDEA] ←→ [JDWP协议] ←→ [远程JVM]
↓ ↓ ↓
JDI JDWP JVMTI
(调试器接口) (调试线协议) (JVM工具接口)
远程JVM启动时加载jdwp代理,通过如下命令
bash
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
JVM启动调试代理,在指定端口监听连接
创建专门的调试线程处理调试通信
然后创建连接你的IDEA通过Socket连接到远程JVM的调试端口
双方建立
JDWP协议会话
断点命中时,目标线程暂停执行IDA通过JDWP协议获取栈帧、变量信息
你可以在IDEA中单步执行、修改变量、评估表达式
所有操作都通过协议指令在远程JVM中实际执行
步骤
在开始之前,首先,你需要有一个开发好的springBoot后端项目,可以配置部署到服务器,具体如果部署,可以参考我的前面的文章
服务器部署启动
首先我们先把我们项目启动项目端口,和远端debug的端口开放,如果有看我前面的文章,教你部署到服务器相关的文章的话,我前面是有使用
宝塔
宝塔里面的【安全】里面要开放对应的端口,如我项目打算启动在8084,远端debug需要启动在5005,则这两个在宝塔界面里面需要开放对应的端口的
防火墙


同时,我在阿里云买的服务器,里面的【云服务器实例】的【网络与安全组】的相应端口也需要开放


开放之后,上传你的项目jar包,我们同样可以使用
【宝塔】
的【网站】
,找到【Java项目】
,点击【添加Java项目】
找到上传的java包打开

然后我们会看到一些配置信息,除了
【项目JDK】
要修改成自己项目的JDK外,我们需要改动【项目启动命令】
,未改动前是这样
bash
// 我的项目jar包命名是ssosV2.jar,所以启动的是这个,最前面是路径
/www/server/java/jdk1.8.0_371/bin/java -jar -Xmx1024M -Xms256M /www/wwwroot/后端/ssosV2.jar
然后将其改造成可启动远端debug
bash
/www/server/java/jdk1.8.0_371/bin/java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -Xmx1024M -Xms256M -jar /www/wwwroot/后端/ssosV2.jar
保存配置之后,启动即可,当然你也可以复制这个启动命令去命令行启动,都是OK的。
启动之后,等待一会,你会看到这个项目启动了两个端口

到此为止,我们的项目就部署好了
然后我项目的启动端口是8084,则我访问项目路径是这样的(我的项目有开启SSL,所以请求的是https,如果没有请求http)

IDEA配置远程DEBUG
这个时候,我们项目已经启动了,我们想要使用IDEA远端debug的话,需要添加运行配置.
点击我们平常启动项目的地方

然后点击
Edit Configuration
,左边有一个+
号,我们点击它,添加一个Remote Jvm Debug
配置,如果你有安装中文插件,它名称应该会叫远程 Jvm 调试

添加之后,我们需要修改我们的
Host
是我们服务器的公网IP
,Port
修改为我们的远端调试启动端口

然后
Apply
应用,点击启动
启动之后,我们会看到控制台
,会出现连接成功的信息,代表连接成功了

然后我们下一个断点

通过
Postman
我们请求刚刚的接口,会发现我们的请求一直停在那里

并且,我们的IDEA,现在已经在DEBUG

这样就实现了我们远端debug,
需要注意的是,必须保持代码和远端的代码一致,否则会debug错乱
在debug过程中,你甚至可以修改值,让其在该请求生效,如我这个是请求登录接口,那么我修改账密一致,上面我们的例子是登录失败,那么我修改之后让其登录成功
注意事项
✨
绝对绝对禁止在生产环境开启Debug,这一点最重要
✨在debug的时候,记得把所有断点清除,只留下需要debug的地方的断点
✨在公共工具类,或者公共方法的地方,最好不要下断点,否则会影响到测试环境其他人员使用和测试验证
✨远程调试debug,需要保持代码一致性,即你debug部分的代码,本机需要和测试环境代码一致
一些问答
能不能让服务器执行我本地的代码?
技术上可以通过一些复杂的配置实现(如共享网络文件系统),但极其不推荐,会引入环境不一致的严重问题
如果我在调试过程中发现了bug,想立即修复测试怎么办?
这是正常的工作流程。正确的做法是:记录问题 → 结束当前调试会话 → 本地修复并测试 → 部署到测试环境 → 重新开始调试验证。
记住:
远程Debug是"诊断工具",不是"部署工具"
。它的价值在于让你能够深入观察生产/测试环境中的真实执行情况,而不是在那里运行你本地的代码。
启动远端debug是所有请求都会受影响吗?
不是的
。只有触发了你设置的断点的请求才会被"拦截"并等待你的调试。
没有断点的请求
:正常在服务器上快速执行,完全不受影响
触发断点的请求
:该特定请求会暂停,等待你的调试操作
代码仍在服务器执行
:你的应用程序依然在测试环境的服务器JVM中正常运行,处理所有请求
控制权交给你
:当执行到你在本地IDEA中设置的断点时,服务器的那个线程会暂停,然后等待你的本地IDEA来"操控"它
你来当"导演"
:你可以在本地IDE中查看变量、单步执行、评估表达式,服务器上的线程会按照你的指令一步步执行
远端DEBUG会执行我本机的逻辑吗?
不会!远程JVM Debug不会执行你本机的代码逻辑。
- 远程Debug的实际工作方式是按照这样
代码执行的位置
执行环境
:代码仍然在远程服务器的JVM中执行
代码来源
:执行的是服务器上已部署的.class文件(编译后的字节码)
本地角色
:你的本地IDEA只是一个"遥控器",可以控制、观察、干预服务器上代码的执行
能否通过evaluation expression这个功能在执行到某个节点的时候修改数据?
是的
,完全可以通过IDEA的Evaluate Expression
功能,在远程调试执行到断点时动态地查看和修改数据。通过Evaluate Expression对变量或状态的修改,
会直接应用于当前连接的远程服务实例
。例如,在调试Web应用时修改了一个用户的会话状态,那么所有使用该服务的用户都可能看到变化,直到此次远程调试结束
结语
通过如上,就可以实现从远程debug到自己本机