一、前言
为什么这里要记录远程调试这篇文章呢,因为当把一个本地项目部署到远程服务器后有可能出现意想不到错误,这个时候通过远程调试能够更清楚的找到bug所在位置。
本篇讲解的调试方式有两种:
1.使用远程 Debug 方式 调试服务器上面的 SpringBoot 项目
2.使用 Alibaba 开源的 Java 诊断工具 Arthas调试(强的一批)
二、远程 Debug
1)准备工作
1.一个能正常运行的项目
2.连接服务器的SSH工具(Xshell)
3.IDEA
2)打包项目
IDEA中通过Maven构建工具将项目打成jar包
这里包名为:
springboot-blog-0.0.1-SNAPSHOT.jar
3)使用Xshell连接到远程服务器启动项目
正常启动:nohup java -jar springboot-blog-0.0.1-SNAPSHOT.jar &
远程调试启动:nohup java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -jar springboot-blog-0.0.1-SNAPSHOT.jar &
address 是项目启动以后对外提供的调试端口,需要在服务器设置对外开放address的端口
4)在IDE上设置远程服务进行Debug调试
1.打开 Idea 的 Run/Debug Configurations 新增一个 Remote
2.填写 Remote 远程配置
3.这里的 JVM 命令行参就是远程调试启动 Jar 时的传参
4.启动 Remote(远程Debug只有小瓢虫按钮)
启动成功会看到 Console 打印 Connected to... 表示连接成功了
5.尽情的开始你的调试吧
启动完成,对需要 Debug 的代码打上断点,剩下的操作步骤就是访问远程服务器对应的业务请求,本地就会同步 Debug。其余的操作与本地 Debug 相同,此处就不再赘述了。
注意:要保证服务器上的代码和本地代码最好一致
三、Arthas 诊断工具
Arthas支持JDK 6+,支持Linux/Mac/Windows,采用命令行交互模式,同时提供丰富的 Tab 自动补全功能,进一步方便进行问题的定位和诊断。
1)Arthas 可以帮助你解决以下问题
- 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
- 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
- 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
- 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
- 是否有一个全局视角来查看系统的运行状况?
- 有什么办法可以监控到JVM的实时运行状态?
- 怎么快速定位应用的热点,生成火焰图?
- 怎样直接从JVM内查找某个类的实例?
2)安装运行 Arthas
1.使用arthas-boot(推荐)
arthas-boot 是 Arthas 的启动程序,它启动后,会列出所有的 Java 进程,输入需要诊断的目标进程序号即可。
下载arthas-boot.jar,然后用java -jar的方式启动:
curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar
打印帮助信息:
java -jar arthas-boot.jar -h
如果下载速度比较慢,可以使用aliyun的镜像:
java -jar arthas-boot.jar --repo-mirror aliyun --use-http
Ps:默认情况下, arthas server 侦听的是 127.0.0.1 这个 IP,如果希望远程可以访问,可以使用 --target-ip 的参数:
java -jar arthas-boot.jar --target-ip x.xx.xxx.xxx
Arthas支持通过 Web Socket来连接。
当在本地启动时,可以访问 http://127.0.0.1:8563/ ,通过浏览器来使用 Arthas。
2.使用as.sh
Arthas 支持在 Linux/Unix/Mac 等平台上一键安装,输入以下命令:
curl -L https://arthas.aliyun.com/install.sh | sh
上述命令会下载启动脚本文件 as.sh 到当前目录,你可以放在任何地方或将其加入到 $PATH 中。
直接在shell下面执行./as.sh
,就会进入交互界面。
也可以执行./as.sh -h
来获取更多参数信息。
3)使用
相关命令:https://arthas.aliyun.com/doc/advanced-use.html
在这里只讲3个命令:
watch:方法执行数据观测
trace:方法内部调用路径,并输出方法路径上的每个节点上耗时
profiler:使用async-profiler对应用采样,生成火焰图
1.watch:方法执行数据观测
该命令可以查看函数的:参数、返回值、异常信息
watch demo.MathGame primeFactors returnObj
watch com.example.demo.arthas.user.UserController * '{params, throwExp}' -x 2
第一个参数是类名,支持通配
第二个参数是函数名,支持通配
第三个参数是定义返回值
-x 2 是为了将结果展开
返回值表达式实际是一个 ognl 表示,支持一些内置对象:
loader、clazz、method、target、params、returnObj、throwExp、isBefore、isThrow、isReturn
watch 命令支持按请求耗时进行过滤:
watch com.example.demo.arthas.user.UserController * '{params, returnObj}' '#cost>200'
Arthas在 watch/trace 等命令时,实际上是修改了应用的字节码,插入增强的代码。显式执行 reset 命令,可以清除掉这些增强代码
2.trace:方法内部调用路径,并输出方法路径上的每个节点上耗时
trace 命令能主动搜索 class-pattern/method-pattern 对应的方法调用路径,渲染和统计整个调用链路上的所有性能开销和追踪调用链路
3.profiler:生成应用热点火焰图
profiler 命令本质上是通过不断的采样,然后把收集到的采样结果生成火焰图。
命令参数
profiler start:启动profiler
profiler getSamples:获取已采集的sample的数量
profiler status:查看profiler状态
profiler stop:停止profiler,生成火焰图;可以指定生成格式为html --format html