专栏首页程序员的时光线上Bug无法复现怎么办?老司机教你一招,SpringBoot远程调试不用愁!

线上Bug无法复现怎么办?老司机教你一招,SpringBoot远程调试不用愁!

前言

  • 在部署线上项目时,相信大家都会遇到一个问题,线上的 Bug 但是在本地不会复现,多么无奈。
  • 此时最常用的就是取到前端传递的数据用接口测试工具测试,比如 POSTMAN,复杂不,难受不?
  • 今天陈某教你一招,让你轻松调试线上的 Bug。文章目录如下:

什么是 JPDA?

  • JPDA(Java Platform Debugger Architecture),即 Java 平台调试体系,具体结构图如下图所示。
  • 其中实现调试功能的主要协议是JDWP协议,在 Java SE 5 以前版本,JVM 端的实现接口是 JVMPI(Java Virtual Machine Profiler Interface),而在 Java SE 5 及以后版本,使用 JVMTI(Java Virtual Machine Tool Interface) 来替代 JVMPI。
  • 因此,如果使用 Java SE 5 之前版本,使用调试功能的命令为:
java -Xdebug -Xrunjdwp:...
  • Java SE 5 及之后版本,使用调试功能的命令为:
java -agentlib:jdwp=...

调试命令

  • 现在开发中最常见的一条远程调试的的命令如下:
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9091 -jar xxx.jar

参数说明

  • 基于前面的调试命令,我们来分析一下基本的参数代表什么意思。

transport

  • 指定运行的被调试应用和调试者之间的通信协议,它由几个可选值:
    1. dt_socket:主要的方式,采用socket方式连接。
    2. dt_shmem:采用共享内存方式连接,仅支持 Windows 平台。

server

  • 指定当前应用作为调试服务端还是客户端,默认为n
  • 如果你想将当前应用作为被调试应用,设置该值为 y,如果你想将当前应用作为客户端,作为调试的发起者,设置该值为n

suspend

  • 当前应用启动后,是否阻塞应用直到被连接,默认值为 y
  • 在大部分的应用场景,这个值为 n,即不需要应用阻塞等待连接。一个可能为 y的应用场景是,你的程序在启动时出现了一个故障,为了调试,必须等到调试方连接上来后程序再启动。

address

  • 暴露的调试连接端口,默认值为 8000
  • 此端口一定不能与项目端口重复,且必须是服务器开放的端口。

onthrow

  • 当程序抛出设定异常时,中断调试。

onuncaught

  • 当程序抛出未捕获异常时,是否中断调试,默认值为 n。

launch

  • 当调试中断时,执行的程序。

timeout

  • 该参数限定为java -agentlib:jdwp=…可用,单位为毫秒ms
  • suspend = y 时,该值表示等待连接的超时;当 suspend = n 时,该值表示连接后的使用超时。

参考命令

  1. -agentlib:jdwp=transport=dt_socket,server=y,address=8000:以 Socket 方式监听 8000 端口,程序启动阻塞(suspend 的默认值为 y)直到被连接。
  2. -agentlib:jdwp=transport=dt_socket,server=y,address=localhost:8000,timeout=5000:以 Socket 方式监听 8000 端口,当程序启动后 5 秒无调试者连接的话终止,程序启动阻塞(suspend 的默认值为 y)直到被连接。
  3. -agentlib:jdwp=transport=dt_shmem,server=y,suspend=n:选择可用的共享内存连接地址并使用 stdout 打印,程序启动不阻塞。
  4. -agentlib:jdwp=transport=dt_socket,address=myhost:8000:以 socket 方式连接到 myhost:8000上的调试程序,在连接成功前启动阻塞。
  5. -agentlib:jdwp=transport=dt_socket,server=y,address=8000,onthrow=java.io.IOException,launch=/usr/local/bin/debugstub:以 Socket 方式监听 8000 端口,程序启动阻塞(suspend 的默认值为 y)直到被连接。当抛出 IOException 时中断调试,转而执行 usr/local/bin/debugstub程序。

IDEA 远程调试示例

  • 首先打包 SpringBoot 项目,在服务器上运行,执行以下命令:
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9190 -jar debug-demo.jar
  • 出现下图的界面,表示运行成功:
  • 然后在 IDEA 中,点击 Edit Configurations,在弹框中点击 + 号,然后选择Remote
  • 填写服务器的地址及端口,点击 OK 即可。
  • 配置完毕后,DEBUG 调试运行即可。
  • 配置完毕后点击保存即可,因为我配置的 suspend=n,因此服务端程序无需阻塞等待我们的连接。我们点击 IDEA 调试按钮,当我访问某一接口时,能够正常调试。

本文分享自微信公众号 - 程序员的时光(gh_9211ec727426)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-05-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 高效磁盘整理分析软件——TreeSize

    工作学习之余,我们打游戏,听音乐,存照片都会占用我们电脑磁盘空间,从而导致磁盘空间不足,也不知道到底是哪些文件占用了大容量。这时,我们就需要一款强大的工具来帮助...

    程序员的时光001
  • 计算机网络类别?性能指标?你都会吗?

    总结: 现在不单单从网络覆盖范围区分局域网和广域网; 而是说应用了广域网技术和局域网技术等等;

    程序员的时光001
  • 连接查询?子查询?看这篇文章就行了!

    当然,这样效果不是很好,读者很难区分bookTypeName到底是t_book表中还是t_bookType表中的字段;

    程序员的时光001
  • 移动端真机调试

    很多时候,我们在进行移动端开发时,都是先在PC端使用手机模拟器进行调试,没有问题后,我们才会在手机端的浏览器进行测试,这个时候,如果没有出现问题,皆大欢喜。但是...

    grain先森
  • 初探Windows用户态调试机制

    最近写Named Pipe Server Using Completion Routines 发现在delphi调试器中会阻塞在:

    战神伽罗
  • 前端调试的那些手段

    在不同的平台,不同的环境下的调试方法也不尽相同,这个系列文章将探索常见的一些前端调试场景,较为系统地整理出一些调试方法。

    书童小二
  • 拒绝了对对象 'sp_sdidebug'(数据库 'master',所有者 'dbo')的 EXECUTE 权限

    在.net中调用时出现“拒绝了对对象 'sp_sdidebug'(数据库 'master',所有者 'dbo')的 EXECUTE 权限” 的错误的解决办法。 ...

    张善友
  • 移动端网页调试

    还有还有,有哪位大佬推荐下前端开发的工作吗,base广州啊,不胜感激~关于我请戳blog下的resume.png?

    嘉明
  • tomcat远程调试javaweb

      当把一个本地项目部署到远程服务器后有可能出现意想不到错误,这个时候通过远程调试能够更清楚的找到bug所在位置。

    用户2038589
  • 安卓从入门到进阶第四章(调试方法)

    首先,Android是一种基于Linux的开放源代码软件栈,为广泛的设备和机型而创建。下图是Android平台的主要组件。

    程序亦非猿

扫码关注云+社区

领取腾讯云代金券