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表示调试时会暂停远程虚拟机。
远程虚拟机
boot-env.ini文件
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-