一、问题与现状
1. 开发调试现状
当我们的代码在线上/测试环境运行出现异常或者业务处理出现问题时,需要进行问题定位,之前的传统做法是:
1)查看异常日志,根据日志定位到出错代码,然后再根据相关参数及异常信息进行推断。
2)当属于业务上存在问题,导致了数据处理错误,则需要通过在业务代码上不断添加日志进行日志查看
3)本地问题复现进行本地debug调试
2. 问题与痛点
1)异常问题需要更细致的进行debug才能够更精准的去定位和解决
2)通过重复加日志有时候无法完全定位到问题原因,还需要不断的去重启服务
3)本地复现的方式存在的弊端是:线上的很多数据本地没有,经常耽误好久的时间来同步数据。
3. 思考
像上述的问题,是否可以在本地调试一样去debug线上/测试环境的代码,这样可以大大提升bug修复的效率。
4.远程调试
IDEA 远程调试为我们提供了解决方案,像运行本地代码一样调试远程主机上的程序,以排查远程程序的BUG或代码执行流程。
二、远程调试分类
1.主动连接
主动连接调试:服务端配置监控端口,本地IDE连接远程监听端口进行调试,一般调试问题用这种方式。
2.被动连接
被动连接调试:本地IDE监听某端口,等待远程连接本地端口。一般用于远程服务启动不了,启动时连接到本地调试分析。
三、启动形式
1.jar形式启动(springboot)
JDK1.5 以上
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -jar springboot.jar
JDK1.4
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005
-jar springboot.jar
nohup $JAVA -verbose:gc -Xloggc:./logs/gc/gc.log -Xms3g -Xmx3g -Xmn1024m -server -Xss256k -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./logs/dump/ -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -XX:+CMSScavengeBeforeRemark -jar -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 $app > /dev/null 2>&1 &
2.以war形式启动(tomcat)
## sudo vim $CATALINA_HOME/bin/catalina.sh
JAVA_OPTS=“agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005"
参数说明
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -jar springboot.jar
-Xdebug:JVM在DEBUG模式下工作;
-Xrunjdwp:JVM使用(java debug wire protocol)来运行调试环境;
transport:监听Socket端口连接方式,常用的dt_socket表示使用socket连接;
server:=y表示当前是调试服务端,=n表示当前是调试客户端;
suspend:=n表示启动时不中断(如果启动时中断,一般用于调试启动不了的问题);
address:表示本地监听的地址和端口
2.1 修改tomcat 下 catalina.sh 将 127.0.0.1 改成 服务器对应ip
2.2 如果设置jdk环境
export JAVA_HOME=/opt/openjdk
export JRE_HOME=/opt/openjdk/jre
2.3 执行 ./catalina.sh jpda start 以调试模式启动
sh catalina.sh jpda start && tail -f ../log/cataliba.2024-07-10.log
四、idea 远程调试
1.Idea 添加远程调试
2.接口调试说明
1、本地代码必须和服务端代码保持一致
2、在需要调试的地方设置断点
3、服务器调试端口需要暴露
2.在需要调试的业务代码处进行断点设置
3.进入断点调试
五、思考
1.是否允许多人同时进行远程调试 ?
不能 只允许一个客户的进行连接
通过 netstat -ano | grep debug端口号 查看连接状态
如果是LISTENE状态,那说明可以连通,如果是 ESTABLISHED状态那说明已经有debug客户端握手连接,连通不了,这也是远程debug的一个缺点,只有一个客户端可以进行debug
2.调试时其他人会不会卡住?
远程调试进行设置断点的时候,会影响到其他用户的操作和请求
3.如何避免调试冲突?
设置断点条件
1)Suspend 设置为 Thread(仅对当前线程生效。程序运行到这个断点时,不影响其他的线程)
2)Condition 根据该断点上方的变量,编写只对自己生效的代码