Arthas 的 watch 指令一直是我排查线上问题时使用最多的指令,没有之一。而按照条件进行 watch 也是很常见的一个需求,例如线上一个方法会有大量的调用,而我们可以按照指定的条件,watch 到我们希望观察的那一次调用。
十多年的高阳网站建设经验,针对设计、前端、开发、售后、文案、推广等六对一服务,响应快,48小时及时工作处理。全网整合营销推广的优势是能够根据用户设备显示端的尺寸不同,自动调整高阳建站的显示方式,使网站能够适用不同显示终端,在浏览器中调整网站的宽度,无论在任何一种浏览器上浏览网站,都能展现优雅布局与设计,从而大程度地提升浏览体验。创新互联建站从事“高阳网站设计”,“高阳网站推广”以来,每个客户项目都认真落实执行。
说实话,我对 Arthas 也没有什么研究,一开始还真不清楚原来 Arthas watch 可以按条件过滤,翻看一下官方文档:https://arthas.aliyun.com/doc/watch#id6
条件表达式的例子
- $ watch demo.MathGame primeFactors "{params[0],target}" "params[0]<0"
- Press Ctrl+C to abort.
- Affect(class-cnt:1 , method-cnt:1) cost in 68 ms.
- ts=2018-12-03 19:36:04; [cost=0.530255ms] result=@ArrayList[
- @Integer[-18178089],
- @MathGame[demo.MathGame@41cf53f9],
- ]
喏,这不是这么明显的例子吗?但是上面的例子,貌似只给出了一些简单的讯息
但是,这个简单的示例,并没有解答我内心其他的疑惑:
带着这些疑问,我记录下了这篇文章,给不了解 Arthas watch 条件表达式的读者们一些参考。
有一些读者可能仅仅是想知道“我该怎么实现使用 Arthas 条件 Watch”,为此,我在本文的第二节先介绍下我平时积累的一些实践命令。
示例方法
- public void methodForWatch(int id, User user) {
- }
User 结构
- @Data
- public class User {
- private String name;
- private int age;
- private List
hobbies; - }
另外准备一些请求,我会在每个示例中执行相同的调用。示例请求:
- 1, new User("hanmeimei", 16, Arrays.asList("pubg", "lol"));
- 2, new User("liming", 17, Collections.singletonList("pubg"));
- 3, new User("tom", 18, Collections.singletonList("running"));
- 4, new User("jacky", 19, Collections.singletonList("food"));
示例 1:过滤 int 类型;过滤 id > 0 的请求
这其实就是官方的示例,我拿过来再贴一遍
- watch moe.cnkirito.arthas.WatchDemo methodForWatch "{params,returnObj}" "params[0]>0" -x 2
示例 2:过滤对象中的字符串类型;过滤 User 中 name = haimeimei 的请求
- watch moe.cnkirito.arthas.WatchDemo methodForWatch "{params,returnObj}" "params[1].getName().equals('liming')" -x 2
这里有三个注意点
示例 3:过滤集合中的元素;过滤对 pubg 感兴趣的 User 相关的请求
- watch moe.cnkirito.arthas.WatchDemo methodForWatch {params,returnObj} "params[1].getHobbies().contains('pubg')" -x 2
示例 4:多个条件表达式
增加请求示例
- 5, new User("kirito", 20, null);
按照示例 3 的 watch 语句执行,会发现 Arthas 直接抛了一个空指针:
- watch failed, condition is: params[1].getHobbies().contains('pubg'), express is: {params,returnObj}, java.lang.NullPointerException: target is null for method contains, visit /Users/xujingfeng/logs/arthas/arthas.log for more details.
需要增加空指针的判断:
- watch moe.cnkirito.actuator.demo.HelloController methodForWatch {params,returnObj} "params[1].getHobbies() != null && params[1].getHobbies().contains('pubg')" -x 2
呐,很简单,可以直接使用 && 增加判断条件。
可能有人要说了,Kirito 啊!你的公众号最近是不是广告发的太多了,深感愧疚,写了一篇没啥深度的原创文章来充数啊!那我当然要反驳啦,其实我看 Arthas 文档的时候也是踩了坑的,索性我将这个过程也分享一下。
可能大家看了上面的示例会觉得这个 condition 表达式不就是跟 Java 里面的表达式差不多吗?但其实我作为一个不太了解 Arthas 的弱鸡,上面的用法纯粹是我摸索出来的,在最开始的时候,参考 github 中的 issue,我使用的其实是其他的方式来实现的条件查询,参考 issue:https://github.com/alibaba/arthas/issues/71。
看下 github 中的 Arthas 开源作者提供的按条件过滤的示例,可以发现跟上文中我介绍的过滤方式好像,有那么一点点的不同。注意上文的示例
- $ watch demo.MathGame primeFactors "{params[0],target}" "params[0]<0"
watch 后的参数是由 4 部分组成的,分别是类名表达式,方法名表达式,观察表达式,条件表达式。
而 issue 中给出的表达式
- $ watch com.taobao.container.Test test "params[0].{? #this.name == null }" -x 2
没有第四部分:条件表达式。过滤条件被放到了观察表达式的对象后,并且不是 Java 里面的表达式,而是 ognl 表达式。
- ognl 表达式官方参考文档:https://commons.apache.org/proper/commons-ognl/language-guide.html
例如使用 ognl 表达式实现上面的示例 2,需要这么写
示例 5:使用 ognl 表达式过滤对象中的字符串类型;过滤 User 中 name = haimeimei 的请求
- watch moe.cnkirito.actuator.demo.HelloController methodForWatch "params[1].{? #this.name == 'hanmeimei'}" -x 2
示例 2 和示例 5 的对比
聊到这里,如果你对 Arthas 比较熟悉,应该已经意识到示例 5 ognl 过滤和示例 2 直接使用条件过滤表达式的区别了。ognl 这种过滤的方式,是针对对象的属性的过滤,无论是否匹配,都会被算进 watch 的匹配次数中,只不过没有匹配到的对象没有输出;而示例 2 中直接使用条件过滤表达式这种方式,更匹配我文首提出的需求,只有被条件表示式命中的请求,才会被算进 watch 次数中。你可以使用 -n 1 来限定 watch 匹配次数,直观地观察到这两个匹配方式的差异。
本文简单介绍了使用 Arthas 条件表达式使用中可能踩到的一些坑,示例 1~4 可以参考,用于过滤一些指定的请求,让线上问题的定位变得更加高效。
分享文章:不会还有人不知道Arthas可以条件过滤进行Watch吧?
本文网址:http://www.shufengxianlan.com/qtweb/news25/549875.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联