目录
1、序言
今天线上出现了个 Bug ,而且比较坑的是涉及到微信相关的东西不能线下调试。传统方式是在代码中各种的日志 log 埋点然后重新部署进行调试,再根据 log 中的信息进行分析。如果你的 log 埋点不合理,就要不停的修改代码、不停的打包部署。有没有什么骚操作避免上面的问题呢?
2、远程调试
当然有解决方案,这就是远程调试(Remote debugging)。远程调试使开发人员能够直接诊断服务器或其它线上进程上的问题,它提供了跟踪线上运行时错误并确定性能瓶颈和问题根源的方法,让你能够像在本地调试一样 Debug 远程服务器。接下来我们将使用流行的 Java IDE,由 JetBrains 出品的 IntelliJ IDEA 来进行远程调试。要让远程服务器运行的代码支持远程调试,则启动的时候必须加上特定的 JVM 参数,这些参数是:
-Xdebug -Xrunjdwp:transport=dt_socket,suspend=n,server=y,address=${debug_port}
其中 debug_port
是服务端开放的调试端口,后续本地配置会用到。
3、使用 IDEA 进行远程调试
IntelliJ IDEA 进行远程调试并不复杂经过下面几个步骤就可以很方便的配置。
3.1 本地参数配置
按照上面图的位置打开配置面板如下:
按照上面的图新建一个 Remote 调试面板,如下:
按照上图所示的顺序结合你自己服务器和本地环境依次进行配置,然后点击确定就行了。其中步骤1 和 3 端口就是我们远端指定的 debug_port
端口号。
3.2 JDWP 协议
这里有一个小小的知识点就是 参数中的 jdwp
。
那么什么是 jdwp
?
JDWP 是 Java Debug Wire Protocol 的缩写,它定义了调试器(debugger)和被调试的 Java 虚拟机(target vm)之间的通信协议。
JDWP 协议介绍
它定义了调试器(debugger)和目标虚拟机(target vm)之间的通信协议。Target vm 中运行着我们要调试的 Java 程序,它与一般运行的 JVM 没有什么区别,只是在启动时加载了 JDWP Agent 从而具备了调试功能。而 debugger 就是我们本地的调试器,它向运行中的 target vm 发送指令来获取 target vm 运行时的状态和控制远程 Java 程序的执行。Debugger 和 target vm 分别在各自的进程中运行,他们之间通过 JDWP 通信协议进行通信。
如果想要详细了解JDWP,请参考另一篇文章 JDWP 协议及实现
3.3 开启远程调试
点击箭头所示的 绿色甲虫按钮 (快捷键 Shift + F9) 就启动调试了,然后设置好本地代码的断点,让远程的逻辑触发断点逻辑就可以进行打断点调试了。
请务必保证本地 debug 的代码与远程部署的代码完全一致,不能发生任何的修改!否则断点将无法命中!
4、知识要点
除了需要保证代码一致外,这里还有一些需要我们注意的地方。调试完毕远程的 JDWP Agent 应该被禁用,也就是将远端的相关参数去掉。另外在调试中远端的日志并不会映射到本地,当然你可以借助一些工具将远程的日志映射到本地以提供更强大的调试功能。
还要记住,虽然远程调试是一个非常强大的工具,但是它并非银弹!生产环境不是调试的合适目标,请勿滥用!
5、说明
正如我在本文中介绍的那样,使用 IntelliJ IDEA 进行远程调试非常简单,只需几个步骤即可使用。有些情况下它很方便地解决了我们的问题。但是它不应该被滥用,应该被合理地使用。