在之前的文章中,我介绍了使用 Btrace 工具进行线上代码的debug (https://www.cnblogs.com/yougewe/p/10180483.html),其大致原理就是通过字节码注入的方式进行辅助排查。

  可以说,btrace 已经给我们的开发调试一带来了许多的方便,我们在上面做任何想要的调试!但是,明显, btrace 的使用还是有一定成本的,比如:安装应用,写调试脚本...

  所以,今天我们再来看一大利器: arthas (阿尔萨斯)

arthas 官网地址:https://alibaba.github.io/arthas/

  arthas 的文档真的写得非常棒,可以说一看就会。

但是我还是想写一下一些自己的文档,毕竟我们往往只会用到其中皮毛功能而已。翻阅其所有文档也还是有点浪费了!

一、为什么要用 Arthas ?

  其实,这个问题在前面已回答,而且,你为什么要用 btrace ? 同理! 具体理由如下:

  1. 可以很方便查到一类是从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
  2. 怀疑自己的代码未被部署到服务器,可以通过命令快速验证服务器上的代码就是本地的代码;
  3. 可以直接通过 arthas 进行线上debug, 查看方法返回值以确认问题所在;
  4. 可以很方便嵌入自己的debug代码,快速验证猜想;
  5. 操作完成后,可以将所有debug代码删除,从而避免影响线上运行;

二、如何安装?

  真的是超级简单哦;1. 先把 arthas  的 工具jar包下载下来; 2. 运行即可;

wget https://alibaba.github.io/arthas/arthas-boot.jar
java -jar arthas-boot.jar

  请问,还能更简单吗?

三、如何解决问题?

  经过上一步安装,并运行之后,就差不多是图形界面操作了。

  第一步,arthas 会检测到目前正在有几个运行中的java程序,你只需按照序号选择就就可以了。这里你就完全置身该应用环境了。接下来就可以 do what ever you want to do 。

下面,我以几个常用问题场景,来简要看看其解决方案如何吧!

问题1. 我如何查找某个只知道大概的类,或者说我想确认某个类是否已被系统加载?

  通过这个问题,我们可以确认一点: 我写的代码是否被部署了。当然,如果是对于 war 包,其实这个问题比较容易解决,因为它是一个个的 class 文件,我们可以直接使用 find 命令查找即可。然而这毕竟只是理想,事实会很复杂!

  所以, arthas 怎么查找一个类?

sc *DispatcharServlet      # 即可以找到需要的类全路径,如果存在的话
sm org.springframework.web.servlet.DispatcherServlet getHandler # 查看某个方法的信息,如果存在的话

  甚至我们可以使用通配符列出所有的方法:

问题2.  如何查看一个class类的具体信息?

  虽然通过上面检查类和方法是否存在,能够解决一部分我们排查代码的问题,但是在我们只是改动一个方法中的稍稍逻辑时,就无法通过类和方法来确认问题,此时就需要进行反编译后进行查看了!

  这事如果要我自己去干,我多半只是将jar包中的class文件,使用 javap 进行反编译成可读字节码,然后很认真地核对类信息! javap 虽然已经在很大程度上减轻了我们的阅读压力,但仍然门槛很高。

  而 使用 arthas 则简单至极:

jad org.springframework.web.servlet.DispatcherServlet # 直接反编译出java 源代码,包含一此额外信息的

问题3. 如何跟踪某个方法的返回值、入参.... ?

  这个问题其实是我们在用 btrace 这样的工具的大部分时候的初衷!虽然 trace 脚本编写并不复杂,但是千篇一律和频繁地更改,也给我们带来了许多麻烦。

  而这在 arthas 就是一个命令的事!

watch com.test.ob testMethod "{params, returnObj, throwExp}" -e -x   # 同时监控入参,返回值,及异常

  如果有异常,直接打印出来,否则出入参直接监控,超级方便!

  这里有支持复杂的 ognl 语法,实现更复杂逻辑,请参考: https://alibaba.github.io/arthas/watch.html

问题4. 查看最繁忙的线程,以及是否有阻塞情况发生?

  查看繁忙的线程,一般我们可以通过 top 等系统命令进行查看,但是那毕竟要很多个步骤,很麻烦。

  而 arthas 则直观明了:

thread -n  # 查看最繁忙的三个线程栈信息
thread # 以直观的方式展现所有的线程情况
thread -b #找出当前阻塞其他线程的线程

问题5. 如何验证自己的代码猜想,临时更改代码运行?

  可能我就是认为其中有一个数字写错了,导致业务出错,但是不太确认,所以想在线上直接验证下!

  基本的经验是,在本地改了代码后,重新打包部署,然后重启观察效果。但是这太慢了!

jad --source-only com.example.demo.arthas.user.UserController > /tmp/UserController.java  # 先反编译出class源码
# 然后使用外部工具编辑内容
mc /tmp/UserController.java -d /tmp # 再编译成class
# 最后,重新载入定义的类,就可以实时验证你的猜测了
redefine /tmp/com/example/demo/arthas/user/UserController.class

  如上,是直接更改线上代码的方式,但是一般好像是编译不成功的。所以,最好是 本地ide 编译成 class 文件后,再上传替换为好!

  总之,已经完全不用重启和发布了!这个功能真的很方便,比起重启带来的代价,真的是不可比的。比如,重启时可能导致负载重分配,选主等等问题,就不是你能控制的了。

问题6. 我如何测试某个方法的性能问题?

  这个问题其实我们一般不太关注,但是当性能成为问题时,则真的要关注了!平时我们使用 进入打印开始时间,退出打印一个结束时间这种方式,还是有点low了!

monitor -c  demo.MathGame primeFactors

  以上命令直接统计 primeFactors 的响应问题:

  更多参考:https://alibaba.github.io/arthas/monitor.html

问题7. 更高级的追踪工具!

  tt (TimeTumple) : 方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测!

tt -t demo.MathGame primeFactors  # 追踪方法的响应时间情况

  trace: 输出方法内部调用路径,并输出方法路径上的每个节点上耗时!

trace demo.MathGame run '#cost > 10' # 据调用耗时过滤

  

总之,你想要进行的调试,应该都能在这里找到实现方案。去查看文档即可!

  我觉得 arthas 有几个非常好的理念: 1. 可视化追踪,简单易用; 2. 独立classloader, 方便代码卸载;3. 完善的文档;

  其实,我们排查问题时,总是费尽周折。然而当问题解决时,又发现简单到不行。

阿里老话:结果很重要,过程也很重要!

线上应用调试利器 --Arthas的更多相关文章

  1. 阿里开源线上应用调试利器 Arthas的背后

    Arthas是一个功能非常强大的诊断工具,功能点很多,例如:jvm信息.线程信息.搜索类中的方法.跟踪代码执行.观测方法的入参和返回参数等等. 作为有追求的程序员,你不仅要知道它能做什么,更要思考它是 ...

  2. 线上问题排查利器Arthas

    官方文档 下载arthas-boot.jar,然后用java -jar的方式启动: curl -O https://alibaba.github.io/arthas/arthas-boot.jar j ...

  3. 线上问题排查神器 Arthas

    线上问题排查神器 Arthas 之前介绍过 BTrace,线上问题排查神器 BTrace 的使用,也说它是线上问题排查神器.都是神器,但今天这个也很厉害,是不是更厉害不好说,但是使用起来非常简单.如果 ...

  4. Java线上问题排查神器Arthas快速上手与原理浅谈

    前言 当你兴冲冲地开始运行自己的Java项目时,你是否遇到过如下问题: 程序在稳定运行了,可是实现的功能点了没反应. 为了修复Bug而上线的新版本,上线后发现Bug依然在,却想不通哪里有问题? 想到可 ...

  5. Java线上问题排查神器Arthas实战分析

    概述 背景 是不是在实际开发工作当中经常碰到自己写的代码在开发.测试环境行云流水稳得一笔,可一到线上就经常不是缺这个就是少那个反正就是一顿报错抽风似的,线上调试代码又很麻烦,让人头疼得抓狂:而且deb ...

  6. 线上问题定位利器 jprofiler

    1.导出dump windows: jps -l   查看Java进行 jmap -dump:format=b,file=webapi.hprof 20840 查看进程,根据进程号导出hprof文件 ...

  7. 调试工具-fiddler:本地资源替换线上调试

    Fiddler是一个http协议调试代理工具,它能够记录并检查所有你的电脑和互联网之间的http通讯,设置断点,查看所有的“进出”Fiddler的数据(指cookie,html,js,css等文件,这 ...

  8. 用fiddler替换线上网页资源调试界面

    fiddler 是一个http协议调试代理工具,它能够记录并检查所有你的电脑和互联网之间的http通讯,设置断点,查看所有进出fiddler的数据(指cookie,html,js,css等文件,这些都 ...

  9. 【原】fiddler修改线上的内容

    摘要:当我们线上的代码出bug了,咋办呢?有时候本地的代码跟线上的代码还是运行环境还是有区别的.比如有些封装的方法需要运动到手机上可以调试,而浏览器是无法调试的.如果不想每次修改完再放上到测试环境看效 ...

随机推荐

  1. IE浏览器getElementsByTagName方法的兼容问题

    今天发现了一个非常可笑的IE兼容问题,环境是IE8,调用getElementsByTagName方法搜索元素,结果集居然自动识别元素的id作为键名,去掉元素定义id才能按正常的数字索引返回. 因为网页 ...

  2. Selenium调用webdriver.chrome()出错

    问题描述: 今天因为在学习要使用selenium这个python库,我下载好了selenium,并且也Import成功了,但是在我使用webdirver.chorme()时,却提示PATH路径中没有c ...

  3. Linux系统中常见文件系统格式

    Windows常用的分区格式有三种,分别是FAT16.FAT32.NTFS格式. 在Linux操作系统里有Ext2.Ext3.Linux swap和VFAT四种格式. FAT16: 作为一种文件名称, ...

  4. 虚拟机配置Openstack常见问题汇总

    之前配置了openstack,遇到一些问题,现在将问题全部汇总记录在这里. (1)问题:主机名字修改不了: 原因:没有进入root状态:或者没有正确打开文件,要打开的是/etc/hostname,结果 ...

  5. Flask构建微电影(二)

    第三章.项目分析.搭建目录及模型设计 3.1.前后台项目目录分析 微电影网站 前台模块 后台模块 前台(home) 数据模型:models.py 表单处理:home/forms.py 模板目录:tem ...

  6. 网上整理的对于Rest和Restful api的理解

    一.什么是Rest? REST不是"rest"这个单词,而是几个单词缩写 -- REpresentational State Transfer 直接翻译:表现层状态转移,但这个翻译 ...

  7. 对try-catch-finally异常处理的最新理解

    try{ ...... }catch(......){ }finally{ ...... } 这个结构是用来处理Java所有可能出现的异常的,这个我很早其实就已经学过,不过最近看了个视频,感觉自己虽然 ...

  8. linux或Mac中./与/

      mac终端命令和linux中命令是一致的,在执行可执行xxx.sh文件时,需要进入xxx.sh文件所在的目录,然后输入./xxx.sh才可以执行成功 1.为什么需要添加./   因为linux/u ...

  9. jQuery中 $.ajax()方法详解

    $.ajax()方法详解 jquery中的ajax方法参数总是记不住,这里记录一下. 1.url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. 2.type: 要求为Strin ...

  10. Doctype作用?标准模式与兼容模式各有什么区别?

    Doctype作用?标准模式与兼容模式各有什么区别? DOCTYPE是document type(文档类型)的简写,用来告诉浏览器的解析器使用哪种HTML或XHTML规范解析页面.DOCTYPE不存在 ...