用arthas轻松排查线上问题

news2024/11/26 0:38:51

你是否在项目中会碰到以下一些问题:

  1. 在代码中打印各种日志来排查,比如方法的入参,出参,及在方法体中打印日志判断走哪行代码
  2. 还有你觉得代码没问题,可是运行出现却是以前的bug,感觉代码没修改,或者别人把你修改好之前的代码部署上去了,你想要看线上部署的是不是你修改的最新代码,把包从服务器上下载下来然后再反编译查看
  3. 有些接口请求很慢,你想知道这个接口的方法调用链中耗时时间,你以前是不是通过切面去打印每个方法的耗时时间,修改代码,重新部署
  4. 当进程CPU飙高或者占用内存较大,你用top命令查看,然后top -H -p x,把十进制转成16进制,然后jstack  x | grep -A 10 y命令排查,会觉得有点麻烦
  5. 当本地程序运行正常,线上代码运行不正常,你可能需要优化一个class几行代码,在线上看是否会运行正常,重新打包部署,会觉得有点麻烦

其实阿里的线上排查工具arthas就可以解决上述问题

下载地址:https://alibaba.github.io/arthas/arthas-boot.jar

直接执行命令:

java -jar arthas-boot.jar

如果出现中文乱码,需要添加参数 -Dfile.encoding=UTF-8 

java  -Dfile.encoding=UTF-8   -jar arthas-boot.jar

 直接输入你要连接的进程号:如 4

进入arthas交互界面

现在根据以下代码来进行测试:

package com.htf.smm.controller;

import com.htf.smm.service.SmmIndexSyncService;
import com.htf.smm.service.impl.TestServiceOne;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.repository.query.Param;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Objects;

@RestController
@RequestMapping("/smm")
public class SmmController {

    @Autowired
    private TestServiceOne testServiceOne;
    
    @RequestMapping("/ycTest")
    public void ycTest(Long time) {
        System.out.println("执行开始,"+time);
        Other other = new Other();
        other.setInfo("其他");
        Coordinate coordinate = new Coordinate();
        coordinate.setX(1);
        coordinate.setY(2);
        coordinate.setOther(other);
        Address address = new Address();
        address.setAddr("昌北");
        address.setCoordinate(coordinate);
        School school = new School();
        school.setName("华东交大");
        school.setAddress(address);
        ParamEntiry paramEntiry = new ParamEntiry();
        paramEntiry.setName("yc");
        paramEntiry.setAge(32);
        paramEntiry.setSchool(school);
        test(paramEntiry);
        System.out.println("执行完毕");
    }

    public ReturnEntity test(ParamEntiry paramEntiry){
        ReturnEntity returnEntity = new ReturnEntity();
        Other other = new Other();
        other.setInfo("其他");
        Coordinate coordinate = new Coordinate();
        coordinate.setX(1);
        coordinate.setY(2);
        coordinate.setOther(other);
        Address address = new Address();
        address.setAddr("昌北");
        address.setCoordinate(coordinate);
        School school = new School();
        school.setName("华东交大");
        school.setAddress(address);
        returnEntity.setSchool(school);
        return returnEntity;
    }
}
package com.htf.smm.controller;

import lombok.Data;

@Data
public class ParamEntiry {
    private  String name;
    private Integer age;
    private School school;
}
@Data
class School{
    private String name;
    private Address address;
}
@Data
class Address{
    private String addr;
    private Coordinate coordinate;
}
@Data
class Coordinate{
    private int x;
    private int y;
    private Other other;
}
@Data
class Other{
    private String info;
}
@Data
public class ReturnEntity {
    private  String name;
    private Integer age;
    private School school;
}
package com.htf.smm.service.impl;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class TestServiceOne {
    private String serviceName = "one";

    @Autowired
    private TestServiceTwo testServiceTwo;
}
package com.htf.smm.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class TestServiceTwo {
    private String serviceName = "two";

    @Autowired
    private TestServiceThree testServiceThree;
}
package com.htf.smm.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class TestServiceThree {
    private String serviceName = "three";

    @Autowired
    private TestServiceFour testServiceFour;
}
package com.htf.smm.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class TestServiceFour {
    private String serviceName = "four";

    @Autowired
    private TestServiceFive testServiceFive;
}

下面来介绍常用的几个命令,watch,trace,stack ,jad,redefine ,thrad 

watch命令

参数名称参数说明
class-pattern类名表达式匹配
method-pattern函数名表达式匹配
express观察表达式,默认值:{params, target, returnObj}
condition-express条件表达式
[b]函数调用之前观察
[e]函数异常之后观察
[s]函数返回之后观察
[f]函数结束之后(正常返回和异常返回)观察
[E]开启正则表达式匹配,默认为通配符匹配
[x:]指定输出结果的属性遍历深度,默认为 1,最大值是 4
[arthas@9388]$ watch com.htf.smm.controller.SmmController test
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 27 ms, listenerId: 5
method=com.htf.smm.controller.SmmController.test location=AtExit
ts=2023-03-01 15:11:33; [cost=0.0424ms] result=@ArrayList[
    @Object[][isEmpty=false;size=1],
    @SmmController[com.htf.smm.controller.SmmController@59fe5960],
    @ReturnEntity[ReturnEntity(name=null, age=null, school=School(name=华东交大, address=Address(addr=昌北, coordinate=Coordinate(x=1, y=2, other=Other(info=其他)))))],
]

默认返回params,target,returnObj({params, target, returnObj})深度为1(-x 1),且函数结束之后(正常返回和异常返回)-f观察,即等于下面这个命令

[arthas@9388]$ watch com.htf.smm.controller.SmmController test "{params, target, returnObj}" -x 1 -f
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 28 ms, listenerId: 7
method=com.htf.smm.controller.SmmController.test location=AtExit
ts=2023-03-01 15:44:01; [cost=0.0398ms] result=@ArrayList[
    @Object[][isEmpty=false;size=1],
    @SmmController[com.htf.smm.controller.SmmController@59fe5960],
    @ReturnEntity[ReturnEntity(name=null, age=null, school=School(name=华东交大, address=Address(addr=昌北, coordinate=Coordinate(x=1, y=2, other=Other(info=其他)))))],
]

@Object[][isEmpty=false;size=1] 为params,为什么是个数组呢?因为参数可能有多个

@SmmController[com.htf.smm.controller.SmmController@59fe5960] 为当前对象

 @ReturnEntity[ReturnEntity(name=null, age=null, school=School(name=华东交大, address=Address(addr=昌北, coordinate=Coordinate(x=1, y=2, other=Other(info=其他)))))] 为returnObj

location=AtExit 为在函数结束之后正常返回观察

重要参数-x,默认为1,但是当参数和当前对象的属性有对象引用的时候,我们就需要用到-x,如上命令执行 @SmmController[com.htf.smm.controller.SmmController@59fe5960] 我们无法查看到当前对象内部有什么属性,@Object[][isEmpty=false;size=1]当前参数的具体值

我们设置-x 2试试

[arthas@9388]$ watch com.htf.smm.controller.SmmController test "{params, target, returnObj}" -x 2 -f
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 29 ms, listenerId: 14
method=com.htf.smm.controller.SmmController.test location=AtExit
ts=2023-03-01 16:01:39; [cost=0.0249ms] result=@ArrayList[
    @Object[][
        @ParamEntiry[ParamEntiry(name=yc, age=32, school=School(name=华东交大, address=Address(addr=昌北, coordinate=Coordinate(x=1, y=2, other=Other(info=其他)))))],
    ],
    @SmmController[
        testServiceOne=@TestServiceOne[com.htf.smm.service.impl.TestServiceOne@55111d28],
    ],
    @ReturnEntity[
        name=null,
        age=null,
        school=@School[School(name=华东交大, address=Address(addr=昌北, coordinate=Coordinate(x=1, y=2, other=Other(info=其他))))],
    ],
]

上述所示,就把参数1对应的对象展示出来了,把当前对象中的对象引用展示出来了,把返回对象的引用给展示出来了

注意:-x的最大值为4

重要参数-n,默认是无限次,当线上执行这个接口比较频繁,我们用运维工具可能会频繁去监听打印这个方法相关的信息,很耗服务器资源,而且影响接口响应耗时的时间,当我们为了排查问题,只要获取到一次监听的时候,就可以加-n参数,-n 1表示只执行两次,执行1次后,就会自动退出监听

[arthas@9388]$ watch com.htf.smm.controller.SmmController test "{params, target, returnObj}" -x 2 -f -n 1
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 30 ms, listenerId: 15
method=com.htf.smm.controller.SmmController.test location=AtExit
ts=2023-03-01 16:12:51; [cost=0.0357ms] result=@ArrayList[
    @Object[][
        @ParamEntiry[ParamEntiry(name=yc, age=32, school=School(name=华东交大, address=Address(addr=昌北, coordinate=Coordinate(x=1, y=2, other=Other(info=其他)))))],
    ],
    @SmmController[
        testServiceOne=@TestServiceOne[com.htf.smm.service.impl.TestServiceOne@55111d28],
    ],
    @ReturnEntity[
        name=null,
        age=null,
        school=@School[School(name=华东交大, address=Address(addr=昌北, coordinate=Coordinate(x=1, y=2, other=Other(info=其他))))],
    ],
]
Command execution times exceed limit: 1, so command will exit. You can set it with -n option.

最后一行Command execution times exceed limit: 1, so command will exit. You can set it with -n option.表示执行次数限制为1次,可以通过-n来设置执行的次数

trace命令

参数名称参数说明
class-pattern类名表达式匹配
method-pattern方法名表达式匹配
condition-express条件表达式
[E]开启正则表达式匹配,默认为通配符匹配
[n:]命令执行次数
#cost方法执行耗时

根据耗时"#cost>0"大小匹配如下,耗时是以s为单位的 

[arthas@9388]$ trace com.htf.smm.controller.SmmController ycTest "#cost>0"
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 36 ms, listenerId: 27
`---ts=2023-03-02 09:54:37;thread_name=http-nio-8080-exec-2;id=4f;is_daemon=true;priority=5;TCCL=org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader@1aa6e3c0
    `---[0.3154ms] com.htf.smm.controller.SmmController:ycTest()
        +---[3.01% 0.0095ms ] com.htf.smm.controller.Other:<init>() #31
        +---[1.49% 0.0047ms ] com.htf.smm.controller.Other:setInfo() #32
        +---[1.81% 0.0057ms ] com.htf.smm.controller.Coordinate:<init>() #33
        +---[1.55% 0.0049ms ] com.htf.smm.controller.Coordinate:setX() #34
        +---[1.20% 0.0038ms ] com.htf.smm.controller.Coordinate:setY() #35
        +---[1.30% 0.0041ms ] com.htf.smm.controller.Coordinate:setOther() #36
        +---[1.30% 0.0041ms ] com.htf.smm.controller.Address:<init>() #37
        +---[1.17% 0.0037ms ] com.htf.smm.controller.Address:setAddr() #38
        +---[1.24% 0.0039ms ] com.htf.smm.controller.Address:setCoordinate() #39
        +---[1.17% 0.0037ms ] com.htf.smm.controller.School:<init>() #40
        +---[1.33% 0.0042ms ] com.htf.smm.controller.School:setName() #41
        +---[1.33% 0.0042ms ] com.htf.smm.controller.School:setAddress() #42
        +---[1.24% 0.0039ms ] com.htf.smm.controller.ParamEntiry:<init>() #43
        +---[1.14% 0.0036ms ] com.htf.smm.controller.ParamEntiry:setName() #44
        +---[1.43% 0.0045ms ] com.htf.smm.controller.ParamEntiry:setAge() #45
        +---[1.24% 0.0039ms ] com.htf.smm.controller.ParamEntiry:setSchool() #46
        `---[3.01% 0.0095ms ] com.htf.smm.controller.SmmController:test() #47

stack命令

参数名称参数说明
class-pattern类名表达式匹配
method-pattern方法名表达式匹配
condition-express条件表达式
[E]开启正则表达式匹配,默认为通配符匹配
[n:]执行次数限制(stack,watch,trace命令用法一致)

根据参数值"params[0].name=='yc'"匹配,用法如下:

[arthas@9388]$ stack com.htf.smm.controller.SmmController test "params[0].name=='yc'"
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 28 ms, listenerId: 37
ts=2023-03-02 10:16:57;thread_name=http-nio-8080-exec-4;id=51;is_daemon=true;priority=5;TCCL=org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader@1aa6e3c0
    @com.htf.smm.controller.SmmController.test()
        at com.htf.smm.controller.SmmController.ycTest(SmmController.java:47)
        at sun.reflect.GeneratedMethodAccessor55.invoke(null:-1)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:483)
        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:105)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792)
        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:626)
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
        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.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:541)
        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.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:690)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373)
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1589)
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:744)

注意:stack命令和trace命令参数值匹配和耗时大小匹配可以联合使用,如下:

[arthas@9388]$ stack com.htf.smm.controller.SmmController test "params[0].name=='yc'" "#cost>0"
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 38 ms, listenerId: 38
ts=2023-03-02 10:23:37;thread_name=http-nio-8080-exec-6;id=53;is_daemon=true;priority=5;TCCL=org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader@1aa6e3c0
    @com.htf.smm.controller.SmmController.test()
        at com.htf.smm.controller.SmmController.ycTest(SmmController.java:47)
        at sun.reflect.GeneratedMethodAccessor55.invoke(null:-1)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:483)
        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:105)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792)
        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:626)
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
        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.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:541)
        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.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:690)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373)
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1589)
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:744)

jad命令

lass-pattern类名表达式匹配
[c:]类所属 ClassLoader 的 hashcode
[classLoaderClass:]指定执行表达式的 ClassLoader 的 class name
[E]开启正则表达式匹配,默认为通配符匹配

反编译类jad 类路径:

[arthas@9388]$ jad com.htf.smm.controller.SmmController

ClassLoader:
+-sun.misc.Launcher$AppClassLoader@58644d46
  +-sun.misc.Launcher$ExtClassLoader@71c7db30

Location:
/E:/code/htf/htf-parent/htf-damp-parent/htf-damp-smm/target/classes/

       /*
        * Decompiled with CFR.
        *
        * Could not load the following classes:
        *  com.htf.smm.controller.Address
        *  com.htf.smm.controller.Coordinate
        *  com.htf.smm.controller.Other
        *  com.htf.smm.controller.ParamEntiry
        *  com.htf.smm.controller.ReturnEntity
        *  com.htf.smm.controller.School
        *  com.htf.smm.service.impl.TestServiceOne
        */
       package com.htf.smm.controller;

       import com.htf.smm.controller.Address;
       import com.htf.smm.controller.Coordinate;
       import com.htf.smm.controller.Other;
       import com.htf.smm.controller.ParamEntiry;
       import com.htf.smm.controller.ReturnEntity;
       import com.htf.smm.controller.School;
       import com.htf.smm.service.impl.TestServiceOne;
       import org.springframework.beans.factory.annotation.Autowired;
       import org.springframework.web.bind.annotation.RequestMapping;
       import org.springframework.web.bind.annotation.RestController;

       @RestController
       @RequestMapping(value={"/smm"})
       public class SmmController {
           @Autowired
           private TestServiceOne testServiceOne;

           public ReturnEntity test(ParamEntiry paramEntiry) {
               ReturnEntity returnEntity = new ReturnEntity();
               Other other = new Other();
/*54*/         other.setInfo("其他");
               Coordinate coordinate = new Coordinate();
/*56*/         coordinate.setX(1);
/*57*/         coordinate.setY(2);
/*58*/         coordinate.setOther(other);
               Address address = new Address();
/*60*/         address.setAddr("昌北");
/*61*/         address.setCoordinate(coordinate);
               School school = new School();
/*63*/         school.setName("华东交大");
/*64*/         school.setAddress(address);
/*65*/         returnEntity.setSchool(school);
/*66*/         return returnEntity;
           }

           @RequestMapping(value={"/ycTest"})
           public void ycTest(Long time) throws InterruptedException {
/*30*/         System.out.println("执行开始," + time);
               Other other = new Other();
/*32*/         other.setInfo("其他");
               Coordinate coordinate = new Coordinate();
/*34*/         coordinate.setX(1);
/*35*/         coordinate.setY(2);
/*36*/         coordinate.setOther(other);
               Address address = new Address();
/*38*/         address.setAddr("昌北");
/*39*/         address.setCoordinate(coordinate);
               School school = new School();
/*41*/         school.setName("华东交大");
/*42*/         school.setAddress(address);
               ParamEntiry paramEntiry = new ParamEntiry();
/*44*/         paramEntiry.setName("yc");
/*45*/         paramEntiry.setAge(Integer.valueOf(32));
/*46*/         paramEntiry.setSchool(school);
/*47*/         this.test(paramEntiry);
/*48*/         System.out.println("执行完毕");
           }
       }

Affect(row-cnt:1) cost in 357 ms.

其中有ClassLoader和Location信息,如果把他去掉,加 --source-only 参数,如下所示:

[arthas@9388]$ jad com.htf.smm.controller.SmmController  --source-only
       /*
        * Decompiled with CFR.
        *
        * Could not load the following classes:
        *  com.htf.smm.controller.Address
        *  com.htf.smm.controller.Coordinate
        *  com.htf.smm.controller.Other
        *  com.htf.smm.controller.ParamEntiry
        *  com.htf.smm.controller.ReturnEntity
        *  com.htf.smm.controller.School
        *  com.htf.smm.service.impl.TestServiceOne
        */
       package com.htf.smm.controller;

       import com.htf.smm.controller.Address;
       import com.htf.smm.controller.Coordinate;
       import com.htf.smm.controller.Other;
       import com.htf.smm.controller.ParamEntiry;
       import com.htf.smm.controller.ReturnEntity;
       import com.htf.smm.controller.School;
       import com.htf.smm.service.impl.TestServiceOne;
       import org.springframework.beans.factory.annotation.Autowired;
       import org.springframework.web.bind.annotation.RequestMapping;
       import org.springframework.web.bind.annotation.RestController;

       @RestController
       @RequestMapping(value={"/smm"})
       public class SmmController {
           @Autowired
           private TestServiceOne testServiceOne;

           public ReturnEntity test(ParamEntiry paramEntiry) {
               ReturnEntity returnEntity = new ReturnEntity();
               Other other = new Other();
/*54*/         other.setInfo("其他");
               Coordinate coordinate = new Coordinate();
/*56*/         coordinate.setX(1);
/*57*/         coordinate.setY(2);
/*58*/         coordinate.setOther(other);
               Address address = new Address();
/*60*/         address.setAddr("昌北");
/*61*/         address.setCoordinate(coordinate);
               School school = new School();
/*63*/         school.setName("华东交大");
/*64*/         school.setAddress(address);
/*65*/         returnEntity.setSchool(school);
/*66*/         return returnEntity;
           }

           @RequestMapping(value={"/ycTest"})
           public void ycTest(Long time) throws InterruptedException {
/*30*/         System.out.println("执行开始," + time);
               Other other = new Other();
/*32*/         other.setInfo("其他");
               Coordinate coordinate = new Coordinate();
/*34*/         coordinate.setX(1);
/*35*/         coordinate.setY(2);
/*36*/         coordinate.setOther(other);
               Address address = new Address();
/*38*/         address.setAddr("昌北");
/*39*/         address.setCoordinate(coordinate);
               School school = new School();
/*41*/         school.setName("华东交大");
/*42*/         school.setAddress(address);
               ParamEntiry paramEntiry = new ParamEntiry();
/*44*/         paramEntiry.setName("yc");
/*45*/         paramEntiry.setAge(Integer.valueOf(32));
/*46*/         paramEntiry.setSchool(school);
/*47*/         this.test(paramEntiry);
/*48*/         System.out.println("执行完毕");
           }
       }

如果不展示行号,加--lineNumber false 参数

[arthas@9388]$ jad com.htf.smm.controller.SmmController  --source-only  --lineNumber false
/*
 * Decompiled with CFR.
 *
 * Could not load the following classes:
 *  com.htf.smm.controller.Address
 *  com.htf.smm.controller.Coordinate
 *  com.htf.smm.controller.Other
 *  com.htf.smm.controller.ParamEntiry
 *  com.htf.smm.controller.ReturnEntity
 *  com.htf.smm.controller.School
 *  com.htf.smm.service.impl.TestServiceOne
 */
package com.htf.smm.controller;

import com.htf.smm.controller.Address;
import com.htf.smm.controller.Coordinate;
import com.htf.smm.controller.Other;
import com.htf.smm.controller.ParamEntiry;
import com.htf.smm.controller.ReturnEntity;
import com.htf.smm.controller.School;
import com.htf.smm.service.impl.TestServiceOne;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping(value={"/smm"})
public class SmmController {
    @Autowired
    private TestServiceOne testServiceOne;

    public ReturnEntity test(ParamEntiry paramEntiry) {
        ReturnEntity returnEntity = new ReturnEntity();
        Other other = new Other();
        other.setInfo("其他");
        Coordinate coordinate = new Coordinate();
        coordinate.setX(1);
        coordinate.setY(2);
        coordinate.setOther(other);
        Address address = new Address();
        address.setAddr("昌北");
        address.setCoordinate(coordinate);
        School school = new School();
        school.setName("华东交大");
        school.setAddress(address);
        returnEntity.setSchool(school);
        return returnEntity;
    }

    @RequestMapping(value={"/ycTest"})
    public void ycTest(Long time) throws InterruptedException {
        System.out.println("执行开始," + time);
        Other other = new Other();
        other.setInfo("其他");
        Coordinate coordinate = new Coordinate();
        coordinate.setX(1);
        coordinate.setY(2);
        coordinate.setOther(other);
        Address address = new Address();
        address.setAddr("昌北");
        address.setCoordinate(coordinate);
        School school = new School();
        school.setName("华东交大");
        school.setAddress(address);
        ParamEntiry paramEntiry = new ParamEntiry();
        paramEntiry.setName("yc");
        paramEntiry.setAge(Integer.valueOf(32));
        paramEntiry.setSchool(school);
        this.test(paramEntiry);
        System.out.println("执行完毕");
    }
}

反编译类中的方法,如下:

[arthas@9388]$ jad com.htf.smm.controller.SmmController test  --source-only  --lineNumber false
public ReturnEntity test(ParamEntiry paramEntiry) {
    ReturnEntity returnEntity = new ReturnEntity();
    Other other = new Other();
    other.setInfo("其他");
    Coordinate coordinate = new Coordinate();
    coordinate.setX(1);
    coordinate.setY(2);
    coordinate.setOther(other);
    Address address = new Address();
    address.setAddr("昌北");
    address.setCoordinate(coordinate);
    School school = new School();
    school.setName("华东交大");
    school.setAddress(address);
    returnEntity.setSchool(school);
    return returnEntity;
}

retransform命令,结合 jad/mc 命令使用

1、jad 命令反编译,然后可以用其它编译器 

[arthas@9388]$ jad com.htf.smm.controller.SmmController   --source-only  --lineNumber false > D:\\\tmp\\\SmmController.java

 

2、修改源码 ,修改了日志输出

 

3、mc 命令来内存编译修改过的代码

[arthas@9388]$ mc  D:\\\tmp\\\SmmController.java -d D:\\\tmp
Memory compiler output:
D:\tmp\com\htf\smm\controller\SmmController.class
Affect(row-cnt:1) cost in 1792 ms.

  

4、用 retransform 命令加载新的字节码 

[arthas@9388]$ retransform D:\\\tmp\\\com\\\htf\\\smm\\\controller\\\SmmController.class
retransform success, size: 1, classes:
com.htf.smm.controller.SmmController

之后调用的时候,日志输出是修改了执行完毕,之前是执行完毕

thread命令

参数名称参数说明
id线程 id
[n:]指定最忙的前 N 个线程并打印堆栈
[b]找出当前阻塞其他线程的线程
[i <value>]指定 cpu 使用率统计的采样间隔,单位为毫秒,默认值为 200
[--all]显示所有匹配的线程

我们用它来排查cpu占比很高的问题 

得知占比cpu最高的线程的id是81,执行命令thread 81,如下:

[arthas@16256]$ thread 81
"http-nio-8080-exec-1" Id=81 RUNNABLE
    at java.io.FileOutputStream.writeBytes(Native Method)
    at java.io.FileOutputStream.write(FileOutputStream.java:307)
    at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
    at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
    at java.io.PrintStream.write(PrintStream.java:482)
    at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
    at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
    at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:104)
    at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:185)
    at java.io.PrintStream.newLine(PrintStream.java:546)
    at java.io.PrintStream.println(PrintStream.java:807)
    at com.htf.smm.controller.SmmController.test(SmmController.java:66)
    at com.htf.smm.controller.SmmController.ycTest(SmmController.java:46)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    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:105)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792)
    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:626)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
    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.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:541)
    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.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:690)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1589)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:744)

 得知在业务代码

    at com.htf.smm.controller.SmmController.test(SmmController.java:66)
    at com.htf.smm.controller.SmmController.ycTest(SmmController.java:46)中有问题

 参考:

  • monitor——方法执行监控

  • watch——方法执行数据观测,查看方法的入参,出参,和当前对象的属性

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

  • stack——输出当前方法之前到当前方法被调用的调用路径

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

  • jad反编译

  • redefine   /xx/xx.class  更新class文件 服务重启就是失效了

  • dashboard看板,thread命令可以排查cpu和内存飙高问题

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/383427.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

120.(leaflet篇)区域下钻,区域钻取

听老人家说:多看美女会长寿 地图之家总目录(订阅之前建议先查看该博客) 文章末尾处提供保证可运行完整代码包,运行如有问题,可“私信”博主。 效果如下所示: 下面献上完整代码,代码重要位置会做相应解释 <!DOCTYPE html> <html>

【RocksDB】Ubuntu20.04下编译rocksdb

前言&#xff1a; 我在刚学rocksdb的时候是在2022年&#xff0c;但是网上的资源很少&#xff0c;查了好久才把rocksdb安装成功&#xff0c;在这里向大家分享一下我的经历&#xff0c;安装过程中也报了很多错误&#xff0c;希望大家不要迷路 首先 在虚拟机里面安装依赖的包以…

python List和常用的方法

List&#xff1a;列表中包含多个数据&#xff0c;数据之间使用逗号分隔&#xff0c;索引从0开始。 空列表&#xff1a; dir&#xff1a;查看列表的所有方法 List常用方法&#xff1a;insert、append&#xff0c;extend、del、remove、pop、clear、count、index 增加insert(索引…

健身房戴耳机的人都喜欢戴哪款耳机健身、最好用健身耳机推荐

对于喜欢健身和运动人群来说&#xff0c;耳机可谓是重中之重了&#xff0c;带上耳机 听着喜欢的音乐&#xff0c;沉浸在自己的世界中&#xff0c;训练状态直接拉满…但是能适合运动佩戴的耳机真的不多&#xff0c;这类耳机要同时具备舒适度、防水性、稳固性、高续航等等性能&am…

coreldraw2023安装包下载及新功能介绍

对于广告标识业来说 coreldraw这个软件&#xff0c;对我们来说绝对不陌生&#xff0c;我从2008年开始接触到广告制作&#xff0c;到现在已经13多年了&#xff0c;从一开始的coreldraw 9红色的热气球开始。就被这个强大的软件所吸引&#xff0c;他有强大的排榜功能已经对位图的处…

zigbee 抓包软件Ubiqua使用详解

zigbee抓包软件使用&#xff08;Ubiqua Protocol Analyzer&#xff09; 添加Zigbee sniffer Dongle设备 add Device>vendor选择Texas Instruments>选择Texas Instruments CC2531>add Device 设置信道 右键设置需要抓包的信道 设置秘钥 单击主菜单Tools>Opt…

arm64虚拟化学习笔记

各种虚拟化对比 虚拟化种类优缺点实现硬件加速虚拟化性能最好&#xff0c;最贵1.vcpu 2.内存stage2 3.虚拟中断 4.arch time全虚拟化纯软件实现&#xff0c;性能差1.qemu串口 2.qemu磁盘半虚拟化软件实现复杂1.Virtio block 设备 2.Virtio net 设备io虚拟化加速移植性差1.PCI设…

java是编译型语言还是解释型语言?

基本概念 什么是编译型语言&#xff1f;编译型语言的首先将源代码编译生成机器语言&#xff0c;再由机器运行机器码&#xff08;二进制&#xff09;&#xff0c;比如C和C. 编译型语言&#xff1a;程序在执行之前需要一个专门的编译过程&#xff0c;把程序编译成 为机器语言的文…

mysql一explain结果分析

1. EXPLAIN简介 使用EXPLAIN关键字可以模拟优化器执行SQL查询语句&#xff0c;从而知道MySQL是如何处理你的SQL语句的。分析你的查询语句或是表结构的性能瓶颈。 ➤ 通过EXPLAIN&#xff0c;我们可以分析出以下结果&#xff1a; 表的读取顺序数据读取操作的操作类型哪些索引可…

【LeetCode】背包问题总结

文章目录一、背包能否装满&#xff1f;416. 分割等和子集1049. 最后一块石头的重量 II二、装满背包有几种方法&#xff1f;494. 目标和518.零钱兑换II377. 组合总和 Ⅳ70. 爬楼梯三、背包装满的最大价值474.一和零四、装满背包最小物品数322. 零钱兑换279.完全平方数一、背包能…

win10+python3.6+cuda9+pytorch1.1.0安装

为了让torch可以使用显卡GPU加速&#xff0c;需要安装对应版本的cudatoolkit和pytorch。这里我的nvidia显卡驱动是9.1版本&#xff0c;只能安装cudatoolkit9。 一般支持gpu加速的显卡大部分都是英伟达nvidia系列&#xff0c;都自带了nvidia驱动&#xff0c;所以不需要安装nvidi…

一次失败的面试经历:我只想找个工作,你却用面试题羞辱我!

金三银四近在咫尺&#xff0c;即将又是一波求职月&#xff0c;面对跳槽的高峰期&#xff0c;很多软件测试人员都希望能拿一个满意的高薪offer&#xff0c;但是随着招聘职位的不断增多&#xff0c;面试的难度也随之加大&#xff0c;而面试官更是会择优录取小王最近为面试已经焦头…

大数据处理学习笔记1.7 Scala类与对象

文章目录零、本节学习目标一、类&#xff08;一&#xff09;类的定义&#xff08;二&#xff09;类的实例化二、单例对象&#xff08;一&#xff09;单例对象概念&#xff08;二&#xff09;案例演示三、伴生对象&#xff08;一&#xff09;伴生对象概念&#xff08;二&#xf…

C++ vector学习与使用

本文皆在vs2015下运行&#xff0c;操作系统不一样结果可能有出入1.vector的介绍及使用1.1 vector的介绍string&#xff1a;动态类型的顺序表&#xff0c;只能存储charvector&#xff1a;动态类型的顺序表&#xff0c;任意类型的元素都可以存储endofstorage表示vector底层空间的…

Java_面向对象

Java_面向对象 1.面向对象概述 ​ 面向对象是一种符合人类思想习惯的编程思想。显示生活中存在各种形态的不同事物&#xff0c;这些食物存在着各种各样的联系。在程序中使用对象来映射现实中的事物&#xff0c;使用对象的关系来描述事物之间的关系&#xff0c;这种思想就是面…

如何使用码匠连接 Redis

目录 在码匠中集成 Redis 在码匠中使用 Redis 关于码匠 Redis 是由 Salvatore Sanfilippo 用 C 语言开发的一款开源的、高性能的键值对存储数据库&#xff0c;它采用 BSD 协议&#xff0c;为了适应不同场景下的存储需求&#xff0c;提供了多种键值数据类型。到目前为止&…

汇川AM402和上位机C#ModebusTcp通讯

目录 一、测试任务 二、测试环境 三、PLC工程 1、组态配置 2、ip地址、端口号 3、全局变量定义 四、C#端Winform程序创建 1创建主界面 2、创建子窗口 3、运行生成&#xff0c;界面效果 4、Modebus协议说明 5、Modebus操作说明 六、测试 1、寄存器读测试 2、MW1300寄…

软件著作权登记申请表填错之后如何修改?软著登记官费有没有续费或年费?软件登记常见问题汇总

什么是计算机软件&#xff1f; 计算机软件是指计算机程序及其有关文档。计算机程序是指能实现一定功能的代码化指令序列&#xff0c;或者符号化语句序列。文档指用来描述程序的内容、组成、设计、功能规格、开发情况、测试结果及使用方法的文字资料和图表&#xff0c;如程序设…

centos7如何远程连接Navicat数据库?

1、登录centos7&#xff0c;启动mysql服务 [rootlocalhost ~]# systemctl start mysqld 2、设置mysql服务开机自启 [rootlocalhost ~]# systemctl enable mysqld [rootlocalhost ~]# systemctl daemon-reload 3、查看mysql服务状态 4、若未更改初始密码&#xff0c;若已更改…

4.基于Label studio的训练数据标注指南:情感分析任务观点词抽取、属性抽取

情感分析任务Label Studio使用指南 1.基于Label studio的训练数据标注指南&#xff1a;信息抽取&#xff08;实体关系抽取&#xff09;、文本分类等 2.基于Label studio的训练数据标注指南&#xff1a;&#xff08;智能文档&#xff09;文档抽取任务、PDF、表格、图片抽取标注等…