arthasを使い始める

前書き

これはJava診断ツールです。
次の同様の問題が発生して途方に暮れた場合、Arthasはそれらの解決を支援します。

  • このクラスはどのjarパッケージからロードされますか?さまざまな種類の関連する例外が報告されるのはなぜですか?
  • 変更したコードが実行されないのはなぜですか?コミットしなかったのでしょうか?間違ったブランチ?
  • 問題が発生した場合、オンラインでデバッグできません。ログを追加することによってのみ再公開できますか?
  • オンラインでユーザーのデータ処理の問題が発生しましたが、オンラインデバッグも不可能であり、オフラインを再現できません。
  • システムの状態を表示するためのグローバルな視点はありますか?
  • JVMのリアルタイムの実行ステータスを監視する方法はありますか?
  • アプリケーションのホットスポットをすばやく見つけてフレームグラフを生成するにはどうすればよいですか?

概要:Arthasは、JVMのアタッチメカニズムを使用して、サービスの継続性に影響を与えることなく、ターゲットプロセスにリアルタイムで接続します。これは、エンジニアがオンラインで問題をトラブルシューティングするのに便利です。

ダウンロード開始

arthasは瓶の形をしています。2つの方法でダウンロードすることをお勧めします

  • フルダウンロード:https://arthas.aliyun.com/download/latest_version?mirror = aliyun、解凍するだけ
  • arthas-boot.jarをダウンロードしてから、java -jarで開始しますcurl -O https://arthas.aliyun.com/arthas-boot.jar java -jar arthas-boot.jar(或者使用镜像,java -jar arthas-boot.jar --repo-mirror aliyun --use-http)(推奨)
    。2番目の方法は、arthasの開始プロセス中に、他のjarパッケージの最新バージョンを自動的にダウンロードすることです。ダウンロード後のディレクトリ構造は次のとおりです。
    ここに画像の説明を挿入
    起動(arthasを起動するためのユーザー権限は、ターゲットプロセスの権限と一致している必要があります)、アプリケーションJavaプロセスを選択します。
$ $ java -jar arthas-boot.jar
* [1]: 35542
  [2]: 71560 arthas-demo.jar

2を入力してから、入力/入力します。Arthasはターゲットプロセスにアタッチし、ログを出力します。

[INFO] Try to attach process 71560
[INFO] Attach process 71560 success.
[INFO] arthas-client connect 127.0.0.1 3658
  ,---.  ,------. ,--------.,--.  ,--.  ,---.   ,---.
 /  O  \ |  .--. ''--.  .--'|  '--'  | /  O  \ '   .-'
|  .-.  ||  '--'.'   |  |   |  .--.  ||  .-.  |`.  `-.
|  | |  ||  |\  \    |  |   |  |  |  ||  | |  |.-'    |
`--' `--'`--' '--'   `--'   `--'  `--'`--' `--'`-----'
 
wiki: https://arthas.aliyun.com/doc
version: 3.0.5.20181127201536
pid: 71560
time: 2018-11-28 19:16:24

$

次に、コマンドラインでarthasによって定義されたコマンドを入力します。

一般的なコマンドの概要

基本的なコマンド

ダッシュボード

リアルタイム情報、スレッド、メモリ、ラムタイムを表示します
ここに画像の説明を挿入

現在最もビジーな上位Nスレッドを表示し、スタックを印刷します

$ thread -n 3
"as-command-execute-daemon" Id=29 cpuUsage=75% RUNNABLE
    at sun.management.ThreadImpl.dumpThreads0(Native Method)
    at sun.management.ThreadImpl.getThreadInfo(ThreadImpl.java:440)
    at com.taobao.arthas.core.command.monitor200.ThreadCommand$1.action(ThreadCommand.java:58)
    at com.taobao.arthas.core.command.handler.AbstractCommandHandler.execute(AbstractCommandHandler.java:238)
    at com.taobao.arthas.core.command.handler.DefaultCommandHandler.handleCommand(DefaultCommandHandler.java:67)
    at com.taobao.arthas.core.server.ArthasServer$4.run(ArthasServer.java:276)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)

    Number of locked synchronizers = 1
    - java.util.concurrent.ThreadPoolExecutor$Worker@6cd0b6f8

"as-session-expire-daemon" Id=25 cpuUsage=24% TIMED_WAITING
    at java.lang.Thread.sleep(Native Method)
    at com.taobao.arthas.core.server.DefaultSessionManager$2.run(DefaultSessionManager.java:85)

"Reference Handler" Id=2 cpuUsage=0% WAITING on java.lang.ref.Reference$Lock@69ba0f27
    at java.lang.Object.wait(Native Method)
    -  waiting on java.lang.ref.Reference$Lock@69ba0f27
    at java.lang.Object.wait(Object.java:503)
    at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)

ジャド

指定されたロード済みクラスのソースコードを逆コンパイルします

$ jad java.lang.String
 
ClassLoader:
 
Location:
 
        /*
         * Decompiled with CFR.
         */
        package java.lang;
 
        import java.io.ObjectStreamField;
        import java.io.Serializable;
...
        public final class String
        implements Serializable,
        Comparable<String>,
        CharSequence {
    
    
            private final char[] value;
            private int hash;
            private static final long serialVersionUID = -6849794470754667710L;
            private static final ObjectStreamField[] serialPersistentFields = new ObjectStreamField[0];
            public static final Comparator<String> CASE_INSENSITIVE_ORDER = new CaseInsensitiveComparator();
...
            public String(byte[] byArray, int n, int n2, Charset charset) {
    
    
/*460*/         if (charset == null) {
    
    
                    throw new NullPointerException("charset");
                }
/*462*/         String.checkBounds(byArray, n, n2);
/*463*/         this.value = StringCoding.decode(charset, byArray, n, n2);
            }
...

再定義

redefine /tmp/Test.class

クラスをホットロードしますが、メソッドパラメータ、メソッド名、戻り値など、クラスのフィールドとメソッドを変更、追加、または削除することはできません。
注:

  • redefineコマンドは、jad / watch / trace / monitor / ttなどのコマンドと競合します。redefineを実行した後、上記のコマンドを再度実行すると、redefineのバイトコードがリセットされます。
  • resetコマンドは、redefineクラスには影響しません。リセットする場合は、元のバイトコードを再定義する必要があります。

見る

これを使用して、メソッドの入力パラメーター、出力パラメーター、例外、現在のオブジェクト、およびその他の情報を監視できます。使用シナリオはもっと複雑です。公式ドキュメントにジャンプしてください。

痕跡

メソッドはパスを内部的に呼び出し、メソッドパス上の各ノードで費やされた時間を出力します。
一般的に使用されるシナリオを使用するには、公式ドキュメントを参照してください

  • コードが実行されているかどうかを確認します
  • パフォーマンスの問題の特定

スタック

呼び出されている現在のメソッドの呼び出しパスを出力します

$ stack demo.MathGame primeFactors
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 36 ms.
ts=2018-12-04 01:32:19;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69
    @demo.MathGame.run()
        at demo.MathGame.main(MathGame.java:16)

いくつかの高度な使用法

上記の内容は公式文書からのものです。要約の目的は学習コストを削減することです。欠落がある場合は、公式Webサイトに移動してください。

おすすめ

転載: blog.csdn.net/qq_28411869/article/details/115180744