1.为什么要用远程调试?

1.本地环境与远程环境为不一致,线上线下数据的不一致,导致有些问题没办法在本地复现。仅靠本地调试无法直接定位问题。

2.本地调试一般有三种方法,一是写测试用例,二是在swagger上测试,需要造数据,比较麻烦。三是通过前端请求打到后端,但这种方法请求会随机打到本机和Dev环境的机器,需要禁用Dev的机器,有可能影响其他人开发。尤其我们现在基本都在泳道上联调,本地调试更无法定位问题。

2.Java远程调试的原理

由于是对源码进行调试,源码经编译后运行在远程服务器上,并且在本地Idea IDE中打开源码。本地虚拟机与远程虚拟机相互通信,远程虚拟机监控自身的栈帧,方法调用等运行信息,本地虚拟机通过Java API提供的可使用的调试接口,向远程虚拟机发送调试命令,并接受显示调试结果。

远程调试的核心:JPDA(Java Platform Debugger Architecture)框架



模块

层次

编程语言

作用

JVMTI

底层

C

JVMTI(JVM Tool Interface)是 Java 虚拟机所提供的 native 编程接口,为需要访问VM状态的全部工具(分析,调试,监控,线程分析和覆盖率分析)提供VM接口。

JDWP

中间层

C

为 Java 调试而设计的一个通讯交互协议,它定义了调试器和被调试程序之间传递的信息的格式。定义 JVMTI 和 JDI 交互的数据格式,包括请求命令、回应数据和错误代码

JDI

高层

Java

定义了调试器(Debugger)所需要的一些调试接口。基于这些接口,本地调试器可以及时地了解远程虚拟机的状态,例如查看目标虚拟机上有哪些类和实例等。另外,调试者还可以控制远程虚拟机的执行,例如挂起和恢复目标虚拟机上的线程,设置断点等。



 

3.怎么远程调试?

本机

Idea Edit Configurations -> + Remote

重要的是远程机器Ip , 端口 ,plus, octo上都可以看到

  • -Xdebug 启用调试。
  • -Xrunjdwp :启用JDWP实现,
    以下是子选项
    transport=dt_socket : JPDA front-end和back-end之间的传输方法。dt_socket表示使用套接字传输。
    address=8080  :远程JVM在8080端口上监听请求。
    server=y   :y表示启动的JVM是被调试者。如果为n,则表示启动的JVM是本机。
    suspend=n : n表示调试时会暂停远程虚拟机。

jvm 远程监控配置 jvm远程调试原理_运维

 

远程虚拟机

boot-env.ini文件

jvm 远程监控配置 jvm远程调试原理_开发工具_02

 

4.通过前端请求进行远程调试,后端打断点失效常见原因

1. 本地与远程代码不一致

  • 分支不一致
  • 代码未更新

2. 远程IP,端口配置错

3.本地源码与二进制代码不一致:实际JVM是基于二进制代码运行的,需要重新编译

 

参考:

https://sq.163yun.com/blog/article/170376356582318080

https://www.ibm.com/developerworks/cn/java/j-lo-jpda1/index.html?ca=drs-