远程调试

为什么需要进行远程调试: 一些程序本地测试没有问题,但是一到线上或者测试环境中就会出现各种bug,但是线上环境又没有IDE,没有办法在线上进行调试,这个时候就需要远程调试来对线上问题进行排查。

1.远程调试流程

1.1 Idea远程调试

  1. [Run]->[Edit Configurations]->[+]->[Remote]
  2. 起一个应用的名称,一般命名:application-remote
  3. Host:127.0.0.1 (第五步解释为什么配置这个IP)
  4. Port: 配置端口
  5. 配置端口转发,这样即使远程ip变化也不需要修改Host,通过秘钥远程连接并进行端口转发:

$ ssh -i ~/.ssh/id_rsa user@hostip -L localPort:targetIp:targetPort -N

1.2 远程调试参数

  • -Xdebug 启用调试特性。
  • -Xrunjdwp: 在目标 VM 中加载 JDWP 实现。它通过传输和 JDWP 协议与独立的调试器应用程序通信。
  • transport 这里通常使用套接字传输。但是在 Windows 平台上也可以使用共享内存传输。
  • server 如果值为 y,目标应用程序监听将要连接的调试器应用程序。否则,它将连接到特定地址上的调试器应用程序。
  • address 这是连接的传输地址。如果服务器为 n,将尝试连接到该地址上的调试器应用程序。否则,将在这个端口监听连接。
  • suspend 如果值为 y,目标 VM 将暂停,直到调试器应用程序进行连接。

2. 远程调试原理

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

JPDA 定义了一个完整独立的体系,它由三个相对独立的层次共同组成,而且规定了它们三者之间的交互方式,或者说定义了它们通信的接口。这三个层次由低到高分别是 Java 虚拟机工具接口(JVMTI),Java 调试线协议(JDWP)以及 Java 调试接口(JDI)。这三个模块把调试过程分解成几个很自然的概念:调试者(debugger)和被调试者(debuggee),以及他们中间的通信器被调试者运行于我们想调试的 Java 虚拟机之上,它可以通过 JVMTI 这个标准接口,监控当前虚拟机的信息;调试者定义了用户可使用的调试接口,通过这些接口,用户可以对被调试虚拟机发送调试命令,同时调试者接受并显示调试结果。在调试者和被调试着之间,调试命令和调试结果,都是通过 JDWP 的通讯协议传输的。所有的命令被封装成 JDWP 命令包,通过传输层发送给被调试者,被调试者接收到 JDWP 命令包后,解析这个命令并转化为 JVMTI 的调用,在被调试者上运行。类似的,JVMTI 的运行结果,被格式化成 JDWP 数据包,发送给调试者并返回给 JDI 调用。而调试器开发人员就是通过 JDI 得到数据,发出指令。图 2 展示了这个过程:

jvisualvm远程监控jvm java 进程 jvm远程调试原理_调试器

2.1 Java 虚拟机工具接口(JVMTI)

JVMTI(Java Virtual Machine Tool Interface)即指 Java 虚拟机工具接口,它是一套由虚拟机直接提供的 native 接口,它处于整个 JPDA 体系的最底层,所有调试功能本质上都需要通过 JVMTI 来提供。通过这些接口,开发人员不仅调试在该虚拟机上运行的 Java 程序,还能查看它们运行的状态,设置回调函数,控制某些环境变量,从而优化程序性能。

2.2 Java 调试线协议(JDWP)

JDWP(Java Debug Wire Protocol)是一个为 Java 调试而设计的一个通讯交互协议,它定义了调试器和被调试程序之间传递的信息的格式。在 JPDA 体系中,作为前端(front-end)的调试者(debugger)进程和后端(back-end)的被调试程序(debuggee)进程之间的交互数据的格式就是由 JDWP 来描述的,它详细完整地定义了请求命令、回应数据和错误代码,保证了前端和后端的 JVMTI 和 JDI 的通信通畅。

2.3 Java 调试接口(JDI)

JDI(Java Debug Interface)是三个模块中最高层的接口,在多数的 JDK 中,它是由 Java 语言实现的。 JDI 由针对前端定义的接口组成,通过它,调试工具开发人员就能通过前端虚拟机上的调试器来远程操控后端虚拟机上被调试程序的运行.

2.4 JDPA层次比较

模块

层次

编程语言

作用

JVMTI

底层

C

获取及控制当前虚拟机状态

JDWP

中介层

C

定义 JVMTI 和 JDI 交互的数据格式

JDI

高层

Java

提供 Java API 来远程控制被调试虚拟机

2.5 IBM非常详细的讲解

JPDA 体系概览

JVMTI 和 Agent 实现

JDWP 协议及实现

Java 调试接口(JDI)

使用Eclipse调试远程代码程序

3.远程调试注意事项

3.1 远程代码与本地代码不一致情况怎么处理。

测试发现,本地修改的代码不能同步到远程,所以本地修改只会对远程的调试造成影响,不会体现新添加效果。
原因:本地编辑器只是启动了一个调试器,并没有真正执行本地环境,修改不会体现效果,只会增加调试难度。
总结:远程调试一定要保证本地代码与远程代码的一致性。如果修改本地请进行本地测试完在上传部署到远程再次进行远程调试。

最近发现了一个好的blog:http://www.10tiao.com/html/142/201702/2650859362/1.html