zoukankan      html  css  js  c++  java
  • 使用Arthas分析线上问题

    引言

    在日常工作中我们遇到问题最常见的处理方式就是查看日志和debug,但有时候遇到线上问题不能debug,碰巧这个地方又没有打印日志怎么办。本文会介绍如何使用Arthas代替debug提高日常开发效率。更多介绍可访问Arthas官网
    开始之前我们要安装两个插件“arthas idea” 和 “ArthasHotSwap”,“arthas idea”是为了高效率生成Arthas命令,“ArthasHotSwap”可以实现简单快捷的热部署。

    案例重现

    引出问题

    遇到的问题是接口返回兜底异常处理,不知道原因,关键地方又没有打日志。怎么办,debug?debug会一直占用环境引起公愤。加日志重新部署?部署时间太长,而且不一定查看日志就能发现问题。接下去将使用Arthas排查问题

    发现问题

    1. 定位到相关的方法
    2. 生成方法观测命令
    // 安装arthas idea插件之后在方法名处右键选watch即会把相关命令复制到剪切板
    // '{params,returnObj,throwExp}' 表示观测对象,这里选择了入参、出参和异常
    // -n 5 表示观测到5次后停止
    // -x 3 表示打印观测对象的时候只打印3层嵌套结
    // '1==1' 为条件表达式,满足条件才会观测,这里可以根据实际情况修改
    watch com.*.CfFinanceAccountingTaxRateController editAccountingTaxRate '{params,returnObj,throwExp}' -v -n 5 -x 3 '1==1'
    


    3. 登陆应用服务器
    4. 安装Arthas

    // Arthas 支持在 Linux/Unix/Mac 等平台上一键安装,请复制以下内容,并粘贴到命令行中,敲 回车 执行即可:
    curl -L https://arthas.aliyun.com/install.sh | sh
    
    1. 运行Arthas
    上述命令会下载启动脚本文件 as.sh 到当前目录,你可以放在任何地方或将其加入到 $PATH 中。
    直接在shell下面执行./as.sh,就会进入交互界面。
    也可以执行./as.sh -h来获取更多参数信息。
    
    1. 执行方法观测命令
    粘贴第二步拷贝的命令,粘贴 回车 即可执行
    
    1. 查看观测结果,此处为官网示例

    8.更进一步解决问题
    截止目前已经发现了问题所在,一般情况同学都是修改代码重新部署测试,我们要做不一般,接下去就轮到ArthasHotSwap热部署插件上场了:
    修改代码 -> maven编译 -> 单击右键选择swap this class -> 热部署命令已经复制到粘贴板 -> 登录远程服务器粘贴并执行热部署命令 -> 热部署成功

    9.一些限制
    arthas redefine有一些限制导致热部署也有同样的限制。热部署时候,不能修改方法名、属性字段,只能修改方法体里面的代码
    redefine 命令和 jad/watch/trace/monitor/tt 等命令会冲突。执行完 redefine 之后,如果再执行上面提到的命令,则会把 redefine 的字节码重置。也就是说,热部署执行完成之后,再执行 jad/watch/trace/monitor/tt 等命令,会使热部署失效,所以在适当的时候还是需要重新部署下。我们也可以采用其他方法规避,比如使用watch的时候,观测其他类的方法,而不是热部署的那个类。

    方法执行的时间隧道

    上面的场景讲到了使用watch命令观测方法执行参数,但是watch是观测方法执行瞬间的情况。如果我们想重现上次的调用该怎么办呢。在日常开发过程中,环境问题是非常影响开发效率的,特别是涉及其他团队的应用的时候,有时候希望上游再次触发一次调用都是很困难的一件事情。Arthas的tt命令可以获取方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测。

    获取tt命令

    安装好arthas idea插件之后,在需要记录执行的方法上面单击右键,选择TimeTunnel Tt

    记录方法执行

    // 登陆服务器,运行Arthas
    // 运行下面复制的命令
    tt -t com.*.CfFinanceAccountingTaxRateController editAccountingTaxRate -n 5 '1==1'
    

    搜索方法执行记录

    // tt -l可以查看所有的方法执行记录,但是我们要和我们相关的执行记录,那么可以使用tt -s命令进行搜索。
    // tt -s 命令后面需要携带过滤条件。条件表达式是使用OGNL编写,下面介绍几个通常的过滤表达式。首先介绍下几个对象,params表示入参,params[0]表示第一个参数,params[1]表示第二个参数,returnObj表示返回对象。
    
    // 根据入参过滤
    tt -s 'params[2].getRecordId() == 110213603'
    
    // 根据返回结果过滤
    tt -s 'returnObj.isSuccess() == false'
    
    // 根据入参和返回结果过滤
    tt -s 'returnObj.isSuccess() == true && params[2].getRecordId() == 110213603'
    
    

    查看方法执行情况

    tt -w 相当于tt下面的watch命令,可以用来查看方法执行情况。使用idea插件获取tt -w 命令更方便

    重新触发

    如果需要重新触发某条记录也是可行的,因为tt命令记录当时调用的情况,所以可以本地发起一次调用,tt -p -i 1000 命令的意思重新触发idex=1000的那条记录。不仅仅可以重新触发,还可以间隔时间内多次触发,tt -p --replay-times 5 --replay-interval 2000 -i 1000 表示重新触发5次,每次间隔2s。

    重新触发的时候我们可能还想再watch下方法执行情况,怎么办呢,另外再打开一个页面登录远程服务器,运行arthas,执行 watch 命令。

    一些限制

    • ThreadLocal 信息丢失
      很多框架偷偷的将一些环境变量信息塞到了发起调用线程的 ThreadLocal 中,由于调用线程发生了变化,这些 ThreadLocal 线程信息无法通过 Arthas 保存,所以这些信息将会丢失。
    • 引用的对象
      tt 命令是将当前环境的对象引用保存起来,但仅仅也只能保存一个引用而已。如果方法内部对入参进行了变更,或者返回的对象经过了后续的处理,那么在 tt 查看的时候将无法看到当时最准确的值。这也是为什么 watch 命令存在的意义。
  • 相关阅读:
    A
    E
    C
    A
    exgcd
    博客
    简单数论
    extended_gcd(扩展欧几里德算法) 青蛙的约会
    扩展欧几里德算法—求解不定方程,线性同余方程
    素数筛 E
  • 原文地址:https://www.cnblogs.com/ding-dang/p/14721863.html
Copyright © 2011-2022 走看看