J'ai essayé d'utiliser l'outil de diagnostic Java Arthas

Arthas

Alibaba Arthas est un outil de surveillance et de profilage des applications Java. La caractéristique est qu'il peut être utilisé sans modifier les paramètres ou redémarrer l'application surveillée. Il y a beaucoup de choses qui peuvent être faites avec Arthas, et je n'utilisais que certaines des fonctions, mais quand je l'ai recherchée à nouveau, j'ai trouvé que je pouvais faire diverses choses, alors j'aimerais aborder l'introduction.

Installer et exécuter

Pour installer et exécuter Arthas, exécutez simplement la commande suivante (pour Linux): Arthas lui-même est une application java, il peut donc être exécuté dans d'autres environnements.

$ curl -O https://arthas.aliyun.com/arthas-boot.jar
$ java -jar arthas-boot.jar
[INFO] arthas-boot version: 3.4.0
[INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER.
* [1]: 631 org.logstash.Logstash
  [2]: 3834 camel-springboot-rest-test-0.0.1-SNAPSHOT.jar

L'application Java en cours d'exécution est affichée dans les deux lignes ci-dessous, entrez donc le processus à surveiller.

2 ★ Cette fois"2"Entrer
[INFO] arthas home: /root/.arthas/lib/3.4.1/arthas
[INFO] Try to attach process 3834
[INFO] Attach process 3834 success.
[INFO] arthas-client connect 127.0.0.1 3658
  ,---.  ,------. ,--------.,--.  ,--.  ,---.   ,---.                           
 /  O  \ |  .--. ''--.  .--'|  '--'  | /  O  \ '   .-'                          
|  .-.  ||  '--'.'   |  |   |  .--.  ||  .-.  |`.  `-.                          
|  | |  ||  |\  \    |  |   |  |  |  ||  | |  |.-'    |                         
`--' `--'`--' '--'   `--'   `--'  `--'`--' `--'`-----'                          
                                                                                

wiki      https://arthas.aliyun.com/doc                                         
tutorials https://arthas.aliyun.com/doc/arthas-tutorials.html                   
version   3.4.1                                                                 
pid       3834                                                                  
time      2020-09-12 01:17:02    

Tableau de bord

Avec la commande de tableau de bord, vous pouvez exécuter un tableau de bord qui peut afficher la liste des threads de l'application java, l'état d'utilisation du tas, etc. Appuyez sur "q" pour quitter.

[arthas@3834]$ dashboard

image.png

fil

Vous pouvez afficher une liste de threads avec la commande thread.

image.png

Vous pouvez afficher les informations d'un fil de discussion spécifique en utilisant [ID de fil de discussion] de la liste ci-dessus.

[arthas@3834]$ thread 156
"Camel (camel-1) thread #1 - ThroughputLogger" Id=156 TIMED_WAITING on java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@74abfe92
    at sun.misc.Unsafe.park(Native Method)
    -  waiting on java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@74abfe92
    at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093)
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

Afficher la trace de la pile

Affiche la trace de pile de la méthode.

stack [classe] [Méthode]
[arthas@4939]$ stack mkyz08.example.HelloRestController hello
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 29 ms, listenerId: 5
ts=2020-09-12 01:47:58;thread_name=http-nio-8080-exec-8;id=18;is_daemon=true;priority=5;TCCL=org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader@710f4dc7
    @mkyz08.example.HelloRestController.hello()
        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:215)
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:142)
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)

 

Pour limiter le nombre d'impressions, procédez comme suit.

stack [classe] [Méthode] -n [Nombre d'exécutions]

Surveiller l'exécution de la méthode

Surveillez les informations telles que les valeurs de retour de méthode, les exceptions et les paramètres. Il peut être exécuté avec la commande watch.

watch [classe] [Méthode] [Autres options]

"{params, returnObj}" affiche la valeur de retour et les paramètres après l'exécution. "-x 2" est la profondeur d'affichage.

[arthas@4939]$ watch mkyz08.example.HelloRestController hello "{params,returnObj}" -x 2 
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 35 ms, listenerId: 19
ts=2020-09-12 05:24:36; [cost=1.155725ms] result=@ArrayList[
    @Object[][
        @String[hoge],
    ],
    @String[Hello World],
]

Utilisez "{params, returnObj} -b" pour afficher la valeur de retour et les paramètres avant d'exécuter la méthode. Bien que la valeur de retour soit spécifiée, elle sera toujours nulle car elle n'a pas encore été exécutée.

[arthas@4939]$ watch mkyz08.example.HelloRestController hello "{params,returnObj}" -x 2 -b
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 36 ms, listenerId: 20
ts=2020-09-12 05:25:06; [cost=0.03669ms] result=@ArrayList[
    @Object[][
        @String[hoge],
    ],
    null,
]

Modifier le niveau de journal

Affichez les informations de l'enregistreur avec la commande logger.

[arthas@4939]$ logger
 name                  ROOT                                                                                                      
 class                 ch.qos.logback.classic.Logger                                                                             
 classLoader           org.springframework.boot.loader.LaunchedURLClassLoader@685f4c2e                                           
 classLoaderHash       685f4c2e                                                                                                  
 level                 INFO                                                                                                      
 effectiveLevel        INFO                                                                                                      
 additivity            true                                                                                                      
 codeSource            jar:file:/root/camel-springboot-rest-test-0.0.1-SNAPSHOT.jar!/BOOT-INF/lib/logback-classic-1.2.3.jar!/    
 appenders             name            CONSOLE                                                                                   
                       class           ch.qos.logback.core.ConsoleAppender                                                       
                       classLoader     org.springframework.boot.loader.LaunchedURLClassLoader@685f4c2e                           
                       classLoaderHash 685f4c2e                                                                                  
                       target          System.out   

Vous pouvez modifier le niveau de journalisation avec la commande suivante.

$ logger --name ROOT --level DEBUG
Update logger level success.

Dans le cas de Spring-Boot, il était nécessaire de spécifier le chargeur de classe avec "-c".

$ logger --name ROOT --level DEBUG -c 685f4c2e
Update logger level success.

Afficher les informations MBean

Vous pouvez afficher les informations MBean avec la commande mbean.

[arthas@4939]$ mbean org.apache.camel:context=MyCamelRestApp,type=routes,* ExchangesCompleted
 OBJECT_NAME         org.apache.camel:context=MyCamelRestApp,type=routes,name="hello world route"                                
--------------------------------------------------------------------------------------------------                               
 NAME                VALUE                                                                                                       
--------------------------------------------------------------------------------------------------                               
 ExchangesCompleted  78                                                                                                          

Obtenez un vidage de tas

Vous pouvez obtenir un vidage de tas avec la commande heapdump.

[arthas@4939]$ heapdump /tmp/dump.hprof
Dumping heap to /tmp/dump.hprof ...
Heap dump file created

Si "--live" est spécifié, FullGC sera exécuté avant l'acquisition du vidage du tas.

[arthas@4939]$ heapdump --live /tmp/dump_live.hprof
Dumping heap to /tmp/dump_live.hprof ...
Heap dump file created

async-profiler

Essayez le profileur de votre application en utilisant async-profiler.

[arthas@4939]$ profiler start
Started [cpu] profiling

#Vérifiez le nombre d'acquisitions d'échantillons de données
[arthas@4939]$ profiler getSamples
2

#Vérifier l'état du profileur
[arthas@4939]$ profiler status
[perf] profiling is running for 19 seconds

[arthas@4939]$ profiler stop
OK
profiler output file: /root/arthas-output/20200912-022458.svg

Si vous arrêtez le profileur avec "arrêt du profileur", le fichier SVG sera généré. Vous pouvez également sortir en HTML. Le graphique de flamme acquis est le suivant.

image.png

Appels de méthode de trace

Vous pouvez tracer l'appel de la méthode avec la commande trace. La trace montre également le temps d'exécution de chaque méthode, vous pouvez donc l'utiliser pour analyser quelle méthode est la plus lente.

[arthas@4939]$ trace mkyz08.example.HelloRestController hello
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 72 ms, listenerId: 7
`---ts=2020-09-12 02:11:16;thread_name=http-nio-8080-exec-3;id=13;is_daemon=true;priority=5;TCCL=org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader@710f4dc7
    `---[1.01167ms] mkyz08.example.HelloRestController:hello()
        +---[0.130848ms] org.apache.camel.CamelContext:getEndpoint() #26
        `---[0.649678ms] org.apache.camel.ProducerTemplate:sendBody() #27

Pour limiter le nombre d'exécutions, procédez comme suit.

trace [classe] [Méthode] -n [Nombre d'exécutions]

Si vous souhaitez extraire uniquement les méthodes qui ont été exécutées pendant la durée spécifiée (100 ms dans l'exemple), procédez comme suit.

trace [classe] [Méthode] '#cost>100'

Non seulement la commande trace, mais vous pouvez également utiliser la commande grep. Par exemple, vous pouvez l'utiliser pour filtrer par package.

[arthas@5716]$ trace mkyz08.example.HelloRestController hello | grep mkyz08
Press Q or Ctrl+C to abort.
    `---[1.459843ms] mkyz08.example.HelloRestController:hello()
        `---[0.066367ms] mkyz08.example.HelloRestController:add() #29

Compilation inversée

Vous pouvez utiliser la commande jad pour effectuer une compilation inverse du bytecode exécuté sur la JVM dans le code source. Il peut être utilisé lorsque vous souhaitez vérifier le code de la méthode affiché par les commandes trace et stack. Il semble qu'il puisse être utilisé dans le but de vérifier si d'autres contenus modifiés sont appliqués au serveur.

[arthas@4939]$ jad mkyz08.example.HelloRestController

ClassLoader:                                                                                                                     
+-org.springframework.boot.loader.LaunchedURLClassLoader@685f4c2e                                                                
  +-sun.misc.Launcher$AppClassLoader@70dea4e                                                                                     
    +-sun.misc.Launcher$ExtClassLoader@7c6908d7                                                                                  

Location:                                                                                                                        
file:/root/camel-springboot-rest-test-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/                                                     

/*
 * Decompiled with CFR.
 * 
 * Could not load the following classes:
 *  org.apache.camel.CamelContext
 *  org.apache.camel.Endpoint
 *  org.apache.camel.ProducerTemplate
 *  org.springframework.web.bind.annotation.RequestMapping
 *  org.springframework.web.bind.annotation.RequestMethod
 *  org.springframework.web.bind.annotation.RestController
 */
package mkyz08.example;

import javax.annotation.Resource;
import org.apache.camel.CamelContext;
import org.apache.camel.Endpoint;
import org.apache.camel.ProducerTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping(value={"/spring"})
public class HelloRestController {
    @Resource
    private ProducerTemplate producer = null;
    @Resource
    private CamelContext context;

    @RequestMapping(method={RequestMethod.GET}, value={"/hello"}, produces={"text/plain"})
    public String hello(String msg) {
        Endpoint end = this.context.getEndpoint("seda:hello_world");
        this.producer.sendBody(end, (Object)msg);
        return "Hello World";
    }
}

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

Échange de classes

Lisez le fichier de classe externe et remplacez-le par la classe dans la JVM.

Restrictions -Les arguments, les noms de méthode et les valeurs de retour ne peuvent pas être modifiés. -Les champs et méthodes de classe ne peuvent pas être modifiés, ajoutés ou supprimés.

[arthas@5716]$ redefine /root/HelloRestController.class 
redefine success, size: 1, classes:
mkyz08.example.HelloRestController

Surveiller les appels de méthode

Utilisez la commande monitor pour surveiller le nombre d'exécutions de méthode, le temps d'exécution moyen, etc.

monitor [classe] [Méthode]

Un exemple du résultat de l'exécution est le suivant. Spécifiez l'intervalle d'affichage (secondes) avec l'option "-c".

[arthas@5716]$ monitor -c 5 mkyz08.example.HelloRestController hello
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 35 ms, listenerId: 3
 timestamp           class                         method                       total     success   fail      avg-rt(m  fail-rat 
                                                                                                              s)        e        
---------------------------------------------------------------------------------------------------------------------------------
 2020-09-12 06:40:2  mkyz08.example.HelloRestCont  hello                        1         1         0         0.40      0.00%    
 4                   roller                                                                                                      

 timestamp           class                         method                       total     success   fail      avg-rt(m  fail-rat 
                                                                                                              s)        e        
---------------------------------------------------------------------------------------------------------------------------------
 2020-09-12 06:40:2  mkyz08.example.HelloRestCont  hello                        9         9         0         0.97      0.00%    
 9                   roller                                                                                                      

 timestamp           class                         method                       total     success   fail      avg-rt(m  fail-rat 
                                                                                                              s)        e        
---------------------------------------------------------------------------------------------------------------------------------
 2020-09-12 06:40:3  mkyz08.example.HelloRestCont  hello                        5         5         0         0.26      0.00%    
 4                   roller       

Afficher les options de VM

[arthas@4939]$ vmoption
 KEY                             VALUE                            ORIGIN                          WRITEABLE                      
---------------------------------------------------------------------------------------------------------------------------------
 HeapDumpBeforeFullGC            false                            DEFAULT                         true                           
 HeapDumpAfterFullGC             false                            DEFAULT                         true                           
 HeapDumpOnOutOfMemoryError      false                            DEFAULT                         true                           
~ Abréviation ~

#Lors du changement de valeur

[arthas@4939]$ vmoption PrintGC true
Successfully updated the vm option.
 NAME     BEFORE-VALUE  AFTER-VALUE                                                                                              
------------------------------------                                                                                             
 PrintGC  false         true   

Autres commandes de base

help -Afficher l'aide
cls -Effacer l'écran
session -Afficher les informations de session en cours
reset - resets enhanced classes. All enhanced classes will be reset to their original states. When Arthas server closes, all these enhanced classes will be reset too
version -Voir la version Arthas
history -Afficher l'historique d'exécution des commandes
quit -Quitter le client Arthas
stop -Arrêter le serveur Arthas
keymap -Afficher les raccourcis clavier Arthas

en conclusion

Ce que j'avais l'habitude de faire avec divers outils peut maintenant être fait avec Arthas. De plus, il existe de nombreuses commandes autres que celles introduites cette fois-ci, veuillez donc les consulter sur le site officiel. La console Web avait également l'air intéressante.

référence

Recommended Posts

J'ai essayé d'utiliser l'outil de diagnostic Java Arthas
J'ai essayé l'outil de micro-benchmarking de Java JMH
J'ai essayé d'utiliser Gson
J'ai essayé d'utiliser TestNG
J'ai essayé d'utiliser Galasa
Outil de diagnostic Arthas Java
J'ai essayé d'utiliser azure cloud-init
J'ai essayé d'utiliser Apache Wicket
J'ai essayé d'utiliser Java REPL
J'ai essayé d'utiliser anakia + Jing maintenant
J'ai essayé d'utiliser Spring + Mybatis + DbUnit
J'ai essayé d'utiliser JOOQ avec Gradle
J'ai essayé d'utiliser l'API Java8 Stream
J'ai essayé d'utiliser JWT en Java
[Android] J'ai essayé d'utiliser la disposition du coordinateur.
J'ai essayé d'utiliser le conteneur Pari gp
J'ai essayé d'utiliser WebAssembly Stadio (version 2018/4/17)
J'ai essayé d'utiliser le mémo Java LocalDate
J'ai essayé d'utiliser Google HttpClient de Java
J'ai essayé d'utiliser l'API Elasticsearch en Java
J'ai essayé d'utiliser Realm avec Swift UI
J'ai essayé d'utiliser UICollectionViewListCell ajouté à partir de Xcode12.
J'ai essayé d'utiliser Scalar DL avec Docker
J'ai essayé d'utiliser OnlineConverter avec SpringBoot + JODConverter
C'est nouveau, mais j'ai essayé d'utiliser Groonga
J'ai essayé d'utiliser OpenCV avec Java + Tomcat
J'ai essayé d'utiliser Junit avec Mac VScode Maven
[Pour les débutants] J'ai essayé d'utiliser JUnit 5 avec Eclipse
J'ai essayé de développer un outil de gestion des effectifs
[Android] J'ai quitté SQLite et essayé d'utiliser Realm
J'ai fait un blackjack avec Ruby (j'ai essayé d'utiliser minitest)
J'ai essayé Spring.
[API] J'ai essayé d'utiliser l'API de recherche par code postal
J'ai essayé de mettre Tomcat
J'ai essayé youtubeDataApi.
J'ai essayé de refactoriser ①
J'ai essayé FizzBuzz.
J'ai essayé d'implémenter un serveur en utilisant Netty
J'ai essayé d'utiliser le profileur d'IntelliJ IDEA
J'ai essayé JHipster 5.1
J'ai essayé d'utiliser une connexion à une base de données dans le développement Android
J'ai essayé d'utiliser la fonction Server Push de Servlet 4.0
J'ai essayé d'utiliser le service KMS (Key Management Service) d'Alibaba Cloud
J'ai essayé de faire fonctionner SQS en utilisant AWS Java SDK
J'ai essayé d'utiliser la boîte à outils de migration pour les fichiers binaires d'application
J'ai essayé d'utiliser Log4j2 sur un serveur Java EE
J'ai essayé d'utiliser YOLO v4 sur Ubuntu et ROS
J'ai essayé d'utiliser l'instruction Extended for en Java
J'ai essayé de gratter un graphique boursier en utilisant Java (Jsoup)
[J'ai essayé] Tutoriel de printemps
J'ai essayé d'exécuter Autoware
J'ai essayé QUARKUS immédiatement
J'ai essayé Spring Batch
J'ai essayé node-jt400 (Programmes)
J'ai essayé node-jt400 (exécuter)
J'ai essayé node-jt400 (Transactions)