arthas idea plugin 插件,arthas 使用更加丝滑起来

一、背景

目前Arthas 官方的工具还不够足够的简单,需要记住一些命令,特别是一些扩展性特别强的高级语法,比如ognl获取spring context 为所欲为,watch、trace 不够简单,需要构造一些命令工具的信息,因此只需要一个能够简单处理字符串信息的插件即可使用。当在处理线上问题的时候需要最快速、最便捷的命令,因此Idea arthas 插件还是有存在的意义和价值的。
目前下载量:已经有900多了。
arthas idea plugin 插件,arthas 使用更加丝滑起来_第1张图片

二、支持的功能

支持的功能都是平时处理最常用的一些功能,一些快捷的链接,在处理紧急问题时候不需要到处查找,都是一些基本的功能,自动复制到剪切板中去,方便快捷。

arthas idea plugin 插件,arthas 使用更加丝滑起来_第2张图片
arthas idea plugin 插件,arthas 使用更加丝滑起来_第3张图片

2.1 watch

arthas idea plugin 插件,arthas 使用更加丝滑起来_第4张图片

watch com.command.idea.plugin.utils.StringUtils toLowerFristChar '{params,returnObj,throwExp}' -n 5 -x 3

2.2 trace

2.2.1 基本trace

trace com.command.idea.plugin.utils.StringUtils toLowerFristChar -n 5

2.2.2 trace -E

arthas 2.1 版本新增功能

trace命令只会trace匹配到的函数里的子调用,并不会向下trace多层。因为trace是代价比较贵的,多层trace可能会导致最终要trace的类和函数非常多。因此Arthas 官方支持 trace -E 特殊获取多个,该插件支持一下trace -E

arthas idea plugin 插件,arthas 使用更加丝滑起来_第5张图片

trace -E com.github.wangji92.arthas.plugin.utils.ClipboardUtils|com.github.wangji92.arthas.plugin.utils.OgnlPsUtils getClassBeanName|setClipboardString -n 5

arthas idea plugin 插件,arthas 使用更加丝滑起来_第6张图片

2.3 static ognl (字段或者方法)

arthas idea plugin 插件,arthas 使用更加丝滑起来_第7张图片

2.3.1 右键static ognl

2.3.2 获取classload命令

必须要获取,不然会找不到classload,arthas 官方获取问题系统的classload,spring 项目应该无法获取到这个class的信息,因此首先执行一下这个命令

sc -d com.command.idea.plugin.utils.StringUtils

arthas idea plugin 插件,arthas 使用更加丝滑起来_第8张图片

2.3.2 复制到界面,获取命令,执行即可

arthas idea plugin 插件,arthas 使用更加丝滑起来_第9张图片

ognl  -x  3  '@com.command.idea.plugin.utils.StringUtils@toLowerFristChar(" ")' -c 8bed358

2.4 Invoke Bean Method

实际上就是根据当前的spring项目中的获取静态的spring context这样可以直接根据这个context直接获取任何的Bean方法,一般在Java后端服务中都有这样的Utils类,因此这个可以看为一个常量! 可以参考:http://www.dcalabresi.com/blog/java/spring-context-static-class/ 有了这个,我们可以跟进一步的进行数据简化,由于在idea这个环节中,可以获取方法参数,spring bean的名称等等,非常的方便。

public class ApplicationContextProvider implements ApplicationContextAware {
    
    private static ApplicationContext context;
 
    public ApplicationContext getApplicationContext() {
        return context;
    }
 
    @Override
    public void setApplicationContext(ApplicationContext ctx) {
        context = ctx;
    }
}

2.4.1 设置获取spring context的上下文

ps 这里可以使用@applicationContextProvider@context 这样,比如还行进行函数调用可以直接使用ognl逗号分割可以继续执行的语法,比如 @applicationContextProvider@context,#springContext.getBean(“name”).todo() 后续我们需要在界面调用任何的方法都会添加上这句话。

arthas idea plugin 插件,arthas 使用更加丝滑起来_第10张图片

2.4.2 右键点击需要调用的方法

这里的策略和static ognl 一样的,本质还是ognl的调用。
arthas idea plugin 插件,arthas 使用更加丝滑起来_第11张图片

ognl  -x  3  '#springContext=@applicationContextProvider@context,#springContext.getBean("arthasInstallCommandAction").actionPerformed(new com.intellij.openapi.actionSystem.AnActionEvent())' -c desw22

特别说明

太复杂的参数不太适用于对于线上问题的诊断,因此方法参数尽可能的简单,这里有一套规则,因为ognl的语法和Java类似的,在获取到参数的时候会进行默认的参数构造处理。
String ——> “”
Number、Byte 、Char ——> 0
Map ——> #{"":" "} ognl 语法
List ——>{}
数组 int[] ——>new int[]{}
other ——> new XXXClass() 参数太复杂了默认直接new了一个
Special 你的参数可能是从springContext中获取,你可以修改表达式
…,#newParam= #springContext.getBean(“beanName”).todo(),#springContext.getBean(“other”).to(#newParam)
这样使用参数定义到你的bash脚本中去,这种属于特殊用法,不具有一般的通用性

2.5 install(linux)

安装脚本,可以一键的通过as.sh 进行执行

curl -sk https://arthas.gitee.io/arthas-boot.jar -o ~/.arthas-boot.jar  && echo "alias as.sh='java -jar ~/.arthas-boot.jar --repo-mirror aliyun --use-http'" >> ~/.bashrc && source ~/.bashrc

arthas idea plugin 插件,arthas 使用更加丝滑起来_第12张图片

2.6 常用特殊用法链接

  • special ognl
  • tt get spring context
  • get error filter
  • dubbo 遇上arthas
  • Arthas实践–jad/mc/redefine线上热更新一条龙
  • ognl 使用姿势

arthas 2.3 版本新增功能

2.7 monitor

方法执行监控(性能问题排查,一段时间内的性能指标) --cycle 10 10 秒统计一次

monitor com.wj.study.demo.generator.ControllerTest wangji -n 10 --cycle 10

arthas idea plugin 插件,arthas 使用更加丝滑起来_第13张图片

2.8 stack

获取方法从哪里执行的调用栈(用途:源码学习调用堆栈,了解调用流程)

[arthas@12293]$ stack com.wj.study.demo.generator.ControllerTest wangji -n 5
Press Q or Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 33 ms.
ts=2020-01-11 23:38:35;thread_name=http-nio-8080-exec-3;id=1e;is_daemon=true;priority=5;TCCL=org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader@50a691d3
    @com.wj.study.demo.generator.ControllerTest.wangji()
        at sun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethodAccessorImpl.java:-2)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:888)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793)
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
        at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:526)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1579)
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)

arthas 2.4 版本新增功能

2.9 Time Tunnel

方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测(可以重新触发,周期触发,唯一缺点对于ThreadLocal 信息丢失[隐含参数]、引用对象数据变更无效)
arthas idea plugin 插件,arthas 使用更加丝滑起来_第14张图片

2.9.1 跟踪记录

tt -t com.wj.study.demo.generator.ControllerTest wangji -n 5

image.png

2.9.2 q 退出跟踪

访问接口一次 q 退出,可以通过 tt -l 获取时光记录列表
image.png

2.9.3 重新触发一次

tt -p -i 1000

arthas idea plugin 插件,arthas 使用更加丝滑起来_第15张图片

2.9.4 获取入参、返回值

tt  -w '{method.name,params,returnObj,throwExp}' -x 3 -i 1000

arthas idea plugin 插件,arthas 使用更加丝滑起来_第16张图片

2.9.5 周期性触发 3次

tt -p --replay-times 3 --replay-interval 2000 -i 1000

arthas idea plugin 插件,arthas 使用更加丝滑起来_第17张图片

2.9.6 全部命令

执行一次TT列表中的1000 tt -p -i 1000  
查看第一个参数 tt  -w params[0] -i 1000 
查看方法执行参数 tt  -w '{method.name,params,returnObj,throwExp}' -x 3 -i 1000
周期性执行 tt -p --replay-times 3 --replay-interval 2000 -i 1000
时光隧道列表 tt -l
删除时光隧道列表 tt --delete-all

arthas 2.5 版本新增功能

2.10 Ognl Set Static Field

参考: https://github.com/alibaba/arthas/issues/641 设置Static Field,这里没有考虑复杂对象,支持简单的参数值得设置,通过反射处理。

ognl -x 3  '#[email protected]@class.getDeclaredField("aLong"),#field.setAccessible(true),#field.set(null,0L)' -c desw22

arthas idea plugin 插件,arthas 使用更加丝滑起来_第18张图片


arthas 2.6 版本新增功能

2.11 Ognl get selected spring property

更加方便线上查询某个配置项是否生效,是否已经更新生效,特别是不确定的情况

脚本

ognl -x 3 '#springContext=@com.wj.study.demo.generator.ApplicationContextProvider@context,#springContext.getEnvironment().getProperty("wangji.text")' -c 18b4aac2

操作图

arthas idea plugin 插件,arthas 使用更加丝滑起来_第19张图片

arthas idea plugin 插件,arthas 使用更加丝滑起来_第20张图片**

执行效果

image.png
**

2.12 Ognl get all spring property

获取spring 中全部的配置项信息,方便分析问题。

脚本

ognl -x 3 '#springContext=@com.wj.study.demo.generator.ApplicationContextProvider@context,#allProperties={},#standardServletEnvironment=#propertySourceIterator=#springContext.getEnvironment(),#propertySourceIterator=#standardServletEnvironment.getPropertySources().iterator(),#propertySourceIterator.{#key=#this.getName(),#allProperties.add("                "),#allProperties.add("------------------------- name:"+#key),#this.getSource() instanceof java.util.Map ?#this.getSource().entrySet().iterator.{#key=#this.key,#allProperties.add(#key+"="+#standardServletEnvironment.getProperty(#key))}:#{}},#allProperties' -c 18b4aac2

操作图

arthas idea plugin 插件,arthas 使用更加丝滑起来_第21张图片

效果图

arthas idea plugin 插件,arthas 使用更加丝滑起来_第22张图片

三、其他

3.1 安装

arthas idea plugin 插件,arthas 使用更加丝滑起来_第23张图片

3.2 快捷键设置

arthas idea plugin 插件,arthas 使用更加丝滑起来_第24张图片

3.3 代码地址

https://github.com/WangJi92/arthas-idea-plugin

3.4 插件开发,发布

参考 插件开发: https://www.jianshu.com/p/722841c6d0a9
就可以看到编译后的zip包了
arthas idea plugin 插件,arthas 使用更加丝滑起来_第25张图片

四、下载地址

https://plugins.jetbrains.com/plugin/13581-arthas-idea,直接搜索arthas 即可下载

五、视频介绍

最早期的版本~应该是1.0版本
arthas idea 使用介绍

六、了解更多

csdn 汪小哥

你可能感兴趣的:(arthas,java,arthas,idea-plugin)