利用idea 对Java进程远程debug

本文详细介绍了如何在IDEA中通过JDPA进行远程Java调试,包括设置RemoteRun/DebugConfiguration、调试Tomcat应用,并提供了避免影响他人正常访问的最佳实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文地址
坚持看到最后,后面有彩蛋!!!
背景/原理介绍:
远程debug的意思是启动一个Java进程,启动一个debugger进程,将两者连接起来,利用debugger来debug Java进程。

事实上目前所有的IDE的debug功能都是通过远程debug方式来实现的,它们都利用了一个叫做JDPA(Java Platform Debugger Architecture)的技术。

利用JDPA我们除了能够在IDE开发的时候debug,也能够将IDE attach到一个生产环境上正在运行的Java进程做debug(事实上这两个场景在本质上是一样的)。

1)把项目导入到IDEA里,因为如果没有源码的话我们没有办法打断点
注意本地代码需要和远程代码保存一致
按照下面步骤新建一个Remote Run/Debug Configuration:
新建configuration步骤
2)除了改个Name,设定Use module classpath(也可以不改),其余的选项不需要修改,直接用默认的就行

这里解释一下各种参数:
Debugger mode:debugger的模式,有两种:attach和listen。

attach的意思是debugger连接到被debug的Java进程,是主动式的。
listen的意思是debugger监听由Java进程发送过来的通信,是被动式的。
Host和Port的设定了被debug的Java进程的Host和Port,实际上这也告诉我们,远程Debug是通过网络进行的。

Command line arguments for remote JVM这个文本框你是不能修改的,它告诉了你如果要这个Java进程能够被远程Debug,那么必须添加这些参数才可以。 所以你要把这里的参数复制出来,后面会用得着。

Use module classpath,该选项设定使用那个module的源代码来debug。

3)如果是jar包启动,把刚才的Command line arguments for remote JVM添加Java启动脚本中。
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -jar xx.jar
如果是war包后面再讲启动流程

4)点击Debug按钮开始debug
在这里插入图片描述
你会发现Console里出现这么一句话Connected to the target VM, address: ‘localhost:5005’, transport: ‘socket’, 这说明debugger已经attach成功了。

5)在代码中打个断点看看效果。

debug一个tomcat应用
实际上debug一个tomcat应用和前面的例子没有什么大的区别。
现在我们要用IDEA来debug,那么先把tomcat停掉。

1)同样需要把项目导入到IDEA里

2)执行tomcat的bin/catalina.sh jpda start,让tomcat可以被debug
或者 在启动脚本中加入agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005(jpda start这种方式相当于启用默认参数,后者这种方式可以修改参数)
3)执行jps -v | grep Bootstrap找到Tomcat进程:

76905 Bootstrap -Djava.util.logging.config.file=... 
-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager 
-Djdk.tls.ephemeralDHKeySize=2048 
-Djava.protocol.handler.pkgs=org.apache.catalina.webresources 
-agentlib:jdwp=transport=dt_socket,address=localhost:8000,server=y,suspend=n 
-Dcatalina.base=... 
-Dcatalina.home=... 
-Djava.io.tmpdir=...

注意上面的-agentlib…address=localhost:8000参数,记住这个端口

4)和前面的例子一样,新建一个Remote Run/Debug Configuration,把端口设定为8000,然后启动

5)然后打个断点试试

如果你想改变Tomcat的端口怎么做?看看bin/catalina.sh你会发现这么一段注释

JPDA_TRANSPORT  (Optional) JPDA transport used when the "jpda start"
                command is executed. The default is "dt_socket".

JPDA_ADDRESS    (Optional) Java runtime options used when the "jpda start"
                command is executed. The default is localhost:8000.

JPDA_SUSPEND    (Optional) Java runtime options used when the "jpda start"
                command is executed. Specifies whether JVM should suspend
                execution immediately after startup. Default is "n".

JPDA_OPTS       (Optional) Java runtime options used when the "jpda start"
                command is executed. If used, JPDA_TRANSPORT, JPDA_ADDRESS,
                and JPDA_SUSPEND are ignored. Thus, all required jpda
                options MUST be specified. The default is:

                -agentlib:jdwp=transport=$JPDA_TRANSPORT,
                    address=$JPDA_ADDRESS,server=y,suspend=$JPDA_SUSPEND

所以你只需要提供JPDA_ADDRESS环境变量参数就行了。比如这样:JPDA_ADDRESS=5005 bin/catalina.sh jpda start

最佳实践(彩蛋)
使用远程debug后的现象:

  1. 在A方法上打断点后,用户a访问A方法会到断点处,用户b访问B方法不会阻塞,正常访问;
  2. 在A方法上打断点后,用户a访问A方法会到断点处,用户b访问A方法会阻塞,下面讲如何解决这个问题(这个应该是大家重点关注的问题,因为大家不希望自己在远程Debug的时候影响其他人的正常访问);
  3. 在A、B方法上打断点后,用户a访问A方法会到断点处,用户b访问B方法会到B断点处;

如何防止自己在远程debug的时候影响到其他人?
在这里插入图片描述在断点处点击鼠标右键,调出上图所示设置

Suspend:
-All会影响所有线程
-Thread只影响当前线程
Condition: 只有满足当前条件的请求会到断点,否则会直接通过

按照上述方式debug方式启动工程后
目前有函数queryDetail(T request),在图中第99行打断点,如果不想影响到其他用户的正常访问,可以将Suspend设置为Thread,有必要的话也可以根据入参设置Condition,只允许满足条件的请求进入断点,这样对正常用户的访问影响更小

参考资料:
https://chanjarster.github.io/post/java-remote-debug/https://blog.csdn.net/weixin_33826268/article/details/88730959

### Intellij IDEA 远程 Debug 配置及调用方法 #### 1. 启动远程服务端的 JVM 调试模式 为了使远程服务器上的 Java 应用能够被调试,需要在启动命令中加入特定的 JVM 参数。以下是常用的参数配置: ```bash -Xdebug -Xrunjdwp:transport=dt_socket,suspend=n,server=y,address=${debug_port} ``` 其中: - `transport=dt_socket` 表示使用套接字传输数据。 - `suspend=n` 表示应用不会等待调试器连接后再启动(如果设置为 `y` 则会暂停直到有调试器连接)。 - `server=y` 表示当前进程作为服务器端接受客户端连接。 - `${debug_port}` 是指定用于调试的端口号,例如 `8000`。 将以上参数添加到远程服务的应用启动脚本中[^3]。如果是 Tomcat 容器,可以在 `catalina.sh` 文件的第一行追加该参数[^5]。 --- #### 2. 创建 IntelliJ IDEA 的 Remote Debug 配置 在本地 IDE 中完成以下操作以创建远程调试配置: 1. 打开菜单栏中的 **Run -> Edit Configurations...**。 2. 点击左上角的加号 (`+`) 并选择 **Remote**。 3. 填写以下字段: - **Name**: 自定义名称,例如 `Remote Debug`. - **Host**: 输入远程服务器的 IP 地址或域名,默认值为 `localhost` 如果是在同一台机器上测试。 - **Port**: 设置与远程服务一致的调试端口,例如 `8000`。 4. 确认无误后点击 OK。 此时,IntelliJ IDEA 已经准备好监听来自远程服务的调试请求[^2]。 --- #### 3. 添加断点并启动调试 1. 在项目代码的关键位置右键单击左侧边距区域,设置断点。 2. 返回至刚才创建的 Remote Debug 配置,点击绿色三角形按钮 (**Debug**) 开始调试。 3. 当远程服务执行到设置了断点的代码行时,IDE 将自动挂起程序,并允许开发者查看变量状态、堆栈信息等细节[^1]。 注意:确保防火墙未阻止调试端口的数据流,必要时需开放对应端口访问权限。 --- #### 4. 测试环境下的实际应用场景 当遇到仅存在于测试环境而非开发环境的问题时,可以通过远程调试快速定位原因而无需依赖繁琐的日志分析过程。相比传统的日志排查方式,这种方法更加高效且直观[^4]。 --- ### 示例代码片段 假设我们要调试一段简单的 Spring Boot 控制器逻辑,可以按照如下方式进行模拟: ```java @RestController @RequestMapping("/example") public class ExampleController { @GetMapping("/test") public String testEndpoint() { int a = 1; int b = 2; // 可在此处设置断点验证传入参数变化情况 return "Result is " + (a + b); } } ``` 通过上述步骤即可实现对该接口内部逻辑的实时监控。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值