アリババのオープンソースのトラブルシューティングツール 「Archas 」

この記事では、**アリババ**のオープンソースの**トラブルシューティングツール「Archas」**の概要と主な機能、そして今日から使い始められる方法を紹介します。

*本ブログは英語版からの翻訳です。オリジナルは[こちら](https://www.alibabacloud.com/blog/troubleshooting-production-issues-with-alibabas-arthas_595426)からご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。*

#Arthasの全機能とは
この記事を書いている時点では[バージョン3.1.1](https://alibaba.github.io/arthas/en/release-notes.html?spm=a2c65.11461447.0.0.26773774iloTj8)ですが、現在のバージョンのArthasの主要な機能を見てみましょう。Arthasは以下のことができます。

- クラスがロードされているかどうかのチェック
- クラスを逆コンパイルしてコードが期待通りに動作していることを確認します。
- クラスローダの統計情報とメソッドの呼び出し情報 (関連するパラメータ、リターンオブジェクト、スローされた例外を含む) を表示します。
- 指定されたメソッド呼び出しのスタックトレースをチェック
- 遅い呼び出しを追跡するためにメソッドの呼び出しをトレースする
- メソッド呼び出しの統計情報（秒当たりのクエリ、応答時間、成功率など）を監視します。
- システムメトリクス、スレッドの状態、CPU 使用率、ガーベージコレクション統計などの項目を監視します。
- コマンドラインとブラウザインタフェースを使用したローカルおよびリモートデバッグのためのtelnetとWebソケットをサポート
- Javaa開発キット6+をサポート
- Linux、MacOS、Windowsをサポート
[このページ](https://github.com/alibaba/arthas/releases?spm=a2c65.11461447.0.0.26773774iloTj8)では、アーサスのリリース情報を全て記載しています。

#Arthasのインストールと実行
Arthasは、Linux、MacOS、Windowsを含む主要なオペレーティングシステムのほとんどで動作します。Arthas のセットアップを始める前に、Java Virtual Machine 6 以降がシステムにインストールされていることを確認する必要があります。一般的に言えば、Arthasは単一の実行可能なJarファイルで構成されていて、Arthasのランナーである[arthas-boot](https://alibaba.github.io/arthas/arthas-boot.jar?spm=a2c65.11461447.0.0.26773774iloTj8&file=arthas-boot.jar)という名前です。

arthas-boostをダウンロードするには、以下のコマンドを使用します。

```
wget https://alibaba.github.io/arthas/arthas-boot.jar
```

その後、以下のコマンドでArthasを管理します。

- 実行：`java -jar arthas-boot.jar`
- ヘルプの取得: `java -jar arthas-boot.jar -h`

#ArthasとArthasコマンドの使い方
Arthas のヘルプコマンド (`-h`) から、診断ツールの特定の機能を有効にしたり、対処したりするための多くのオプションがあることがわかります。ここでは、よく使われるであろう興味深いオプションをいくつか紹介します。

- `--target-IP`:ターゲットの Java 仮想マシンがネットワーク上の特定の IP アドレスにある場合、デフォルトは 127.0.0.0.1 (ローカルホスト) です。
- `--telnet-port`:対象の Java 仮想マシンが telnet ポートをリッスンします。デフォルトのポートは3658です。
- `--http-port`: 対象となる Java 仮想マシンのリッスンする HTTP ポート。対象の Java 仮想マシンがリッスンする HTTP ポート。デフォルトのポートは 8563 です。
- `--use-version`: 対象となるJava仮想マシンのバージョンを指定します。Arthas の特別なバージョンを使用します。
- `--use-http`: アイテムのダウンロードに HTTP を使用することを強制します。デフォルトではHTTPSが使用されます。
- `—verbose`: デバッグ情報をより多く表示するためにコードを冗長にします。デバッグ情報をより多く表示するために、コードをより冗長します。

#ターミナルコンソールの使用
Arthas が起動して起動したら、Enter をクリックして Arthas に飛び込むことができます。次に、Arthasに関連付けられたコマンドラインインターフェースを使って、Arthasサーバーに追加のコマンドを入力します。ここでは、この記事で紹介している例では、ローカルマシンなので `--target-ip` を指定していません。

以下はターミナルがどのように見えるかの例です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/c3dd2c7a-92be-f04b-274a-a92208dcd717.png)

ヘルプを入力してEnterキーをクリックすると、内部プロンプトから追加のヘルプを受け取ることができます。現在のマシンの結果は以下の通りです。

```
$ help
 NAME         DESCRIPTION                                                                                                                      
 help         Display Arthas Help                                                                                                              
 keymap       Display all the available keymap for the specified connection.                                                                   
 sc           Search all the classes loaded by JVM                                                                                             
 sm           Search the method of classes loaded by JVM                                                                                       
 classloader  Show classloader info                                                                                                            
 jad          Decompile class                                                                                                                  
 getstatic    Show the static field of a class                                                                                                 
 monitor      Monitor method execution statistics, e.g. total/success/failure count, average rt, fail rate, etc.                               
 stack        Display the stack trace for the specified class and method                                                                       
 thread       Display thread info, thread stack                                                                                                
 trace        Trace the execution time of specified method invocation.                                                                         
 watch        Display the input/output parameter, return object, and thrown exception of specified method invocation                           
 tt           Time Tunnel                                                                                                                      
 jvm          Display the target JVM information                                                                                               
 ognl         Execute ognl expression.                                                                                                         
 mc           Memory compiler, compiles java files into bytecode and class files in memory.                                                    
 redefine     Redefine classes. @see Instrumentation#redefineClasses(ClassDefinition...)                                                       
 dashboard    Overview of target jvm's thread, memory, gc, vm, tomcat info.                                                                    
 dump         Dump class byte array from JVM                                                                                                   
 options      View and change various Arthas options                                                                                           
 cls          Clear the screen                                                                                                                 
 reset        Reset all the enhanced classes                                                                                                   
 version      Display Arthas version                                                                                                           
 shutdown     Shutdown Arthas server and exit the console                                                                                      
 session      Display current session information                                                                                              
 sysprop      Display, and change the system properties.                                                                                       
 sysenv       Display the system env.                                                                                                          
 history      Display command history                                                                                                          
 cat          Concatenate and print files                                                                                                      
 pwd          Return working directory name    
```

上記の結果から、Arthasの本番診断に役立ついくつかの追加コマンドを簡単に見つけることができます。では、以下の行でそのいくつかを見てみましょう。

まず、[ダッシュボード](https://arthas.aliyun.com/doc/en/dashboard.html?spm=a2c65.11461447.0.0.26773774iloTj8)コマンドがあります。これは、以下の画像に示すように、現在のJava仮想マシンのスレッド、CPU使用量、メモリ使用量、コンピュータアーキテクチャ、オペレーティングシステムの概要を、いくつかの追加情報とともにリアルタイムで提供します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/28e4d38a-789b-e7c5-b6f0-716d674fdf54.png)


次に、[classloader](https://arthas.aliyun.com/doc/en/classloader.html?spm=a2c65.11461447.0.0.26773774iloTj8) コマンドはクラスの読み込み情報を表示するために使用されます。他にも、すべてのクラスのインスタンスを完全にリストアップする(`-l`)や、クラスローダの階層を表示する(`-t`)などのオプションがあります。

また、クラスをデコンパイルするための素晴らしいツールである [jad](https://arthas.aliyun.com/doc/en/jad.html?spm=a2c65.11461447.0.0.26773774iloTj8) コマンドもあります。どのように動作するかというと、本番環境で実行されている正確なクラスコードを見つけることができるので、実行されているコードが実際にオンラインで実行したいコードであることを確認することができます。これは比較的簡単なコマンドで、ここに示されているクラス名に続きます: `jad java.lang.String`。このコマンドの結果、コンソールにStringクラスがデコンパイルされていることになります。

クラスのソース・コードのみをデコンパイルして、指定した場所のファイルに保存するより高度な方法は、次のようになります: `jad -source-only java.lang.String > /tmp/String.java`。このため、ここでは `-source-only` を使用して、デコンパイルされたクラスの先頭からいくつかの特定のクラス・ローダと場所の記述を削除しています。

[getstatic](https://arthas.aliyun.com/doc/en/getstatic.html?spm=a2c65.11461447.0.0.26773774iloTj8) コマンドは、クラスの静的フィールド値を表示するために使用されます。そのための構文は次のようになります。`getstatic package.to.Class staticFieldName.`。そしてもう一つの例：`getstatic java.lang.String serialVersionUID` は、以下のように文字列のシリアル・バージョン UID 値を表示します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/8560e4c1-9851-c096-812f-b46796334fbd.png)


[jvm](https://arthas.aliyun.com/doc/en/jvm.html?spm=a2c65.11461447.0.0.26773774iloTj8)コマンドは、Java仮想マシンの全結果を表示するために使用されます。次に、[sc](https://arthas.aliyun.com/doc/en/sc.html?spm=a2c65.11461447.0.0.26773774iloTj8)は、JVMがロードしたすべてのクラスを検索クラスとして読み込むことができます。これは、クラスのロードの問題を検出するのに便利です。

これに続いて、`-d` オプションは、検索されたクラスに関連する特定の情報を出力します。これらの情報は、それがどのようなクラスであるかを判断するために使用することができます。例えば、それがインターフェイスなのか、アノテーションなのか、列挙なのかを判断することができます。`java.lang.String`チェックの結果を、`-d`オプションを指定した場合としなかった場合の画像を以下に示します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/35a6c7cd-6469-b8b0-b411-4a97e4551370.png)

`sc` はワイルドカード文字もサポートしており、特定の一致するクラスを含むすべてのクラスを表示するなど、より多くの結果を表示するのに役立ちます。これは以下のような構文で行うことができます: `sc String*`. 以下の出力例を参照してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/1480e54c-bb7d-b858-ffdf-236d04fc16ea.png)


`sm`は検索メソッドの略で、ロードされたクラスのメソッドを検索してコンソールに表示するために使用されます。d オプションは、修飾子、アノテーション、パラメータ、戻り値の型、例外などの単一のメソッド情報を検索する際に特に便利です。

###その他の例
また、以下のコマンドを使用することもできます。

```
- sm java.lang.String
- sm -d java.lang.String toString
```

どれにしても、次のような結果になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/03221a69-2942-bdc4-015e-d74d13b45849.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/720a104d-c1ca-c4cf-0970-a93fd0826976.png)


次に、現在のJVM環境変数をコンソールに表示できる[sysenv](https://arthas.aliyun.com/doc/en/sysenv.html?spm=a2c65.11461447.0.0.26773774iloTj8)を使用することもできます。また、以下のスクリーンショットのように、[keymap](https://arthas.aliyun.com/doc/en/keymap.html?spm=a2c65.11461447.0.0.26773774iloTj8)コマンドを実行して現在のキーマップを印刷することもできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/591b6f74-5a9f-12ad-5417-d733c46218b4.png)

他にもよく使うコマンドに`thread`がありますが、これは以下のように、すべてのJavaスレッド情報を1つのテーブルに表示するために使うことができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/6677de86-30ed-da1d-b8bd-74c32633ac2f.png)

特定のスレッドのスタックを表示するには、例えば`thread 40` のように、対応するスレッド ID を持つコマンドを実行するだけです。別の例として、`thread -n 3`を使うことでスタックトレースを詳細に表示して、最も使用頻度の高いスレッドの上位 3 つをリストアップすることもできますし、代わりに`thread –b` を使ってすべてのブロッキングスレッドを見つけてリストアップすることもできます。これらがどのように動作するかについての詳細な情報は[このドキュメント](https://arthas.aliyun.com/doc/en/thread.html?spm=a2c65.11461447.0.0.26773774iloTj8)をチェックしてください。

次に [watch](https://arthas.aliyun.com/doc/en/watch.html?spm=a2c65.11461447.0.0.26773774iloTj8) があります。これはクラスのメソッドの戻り値、例外、パラメータを監視します。watchコマンドを使った例を考えてみましょう。以下のように実行したとします。

```
watch package.to.*Controller * '{params, returnObj, throwExp}'
```

上記では、1つ目のパラメータはワイルドカードをサポートしているクラス名で、2つ目のパラメータはメソッドです。これもたまたまワイルドカードの使用をサポートしています。このコマンドは全体として、リアルタイムでパラメータを表示し、任意のコントローラメソッドが呼び出された場合、または呼び出された場合にオブジェクトと例外を返します。このコマンドはデバッグにかなり便利です。

注意点としては、以下のようなものがあります。

- `*Controller` は UserController, BillingController, AuthController, IndexController などとマッチします。
- watch コマンドは `-e` オプションをサポートしており、例外をスローするリクエストのみを検出します。

Arthas-demo プロジェクトを使用する際の他の良い例は[ドキュメント](https://arthas.aliyun.com/doc/en/quick-start.html?spm=a2c65.11461447.0.0.26773774iloTj8#watch)からアクセスできます。

コンソールインターフェイスでは、Arthas はオートコンプリート機能をサポートしています。また、Tab キーをクリックするだけで、最初に入力した単語に応じて、いくつかの異なるクラスのパッケージ間を移動して、より多くの提案を得ることができます。

下の画像は .string と入力したときに表示されるオートコンプリートの提案を示しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/fc2fc217-2309-22f9-1e49-1a536e62d510.png)


[trace](https://arthas.aliyun.com/doc/en/trace.html?spm=a2c65.11461447.0.0.26773774iloTj8)コマンドは、指定されたメソッド呼び出しの実行時間をトレースします。これは、最初のレベルのメソッド呼び出しのみがトレースされ、ディープトレースは行われないので、Javaアプリケーションにあるかもしれないパフォーマンス上の欠陥を判断するのに役立ちます。

次のように考えてみましょう: `trace package.to.Class method '#cost > 50’`。このメソッドは、時間コストが50ms以上になると、クラスメソッド関数の実行をトレースして表示します。

次に、[stack](https://arthas.aliyun.com/doc/en/stack.html?spm=a2c65.11461447.0.0.26773774iloTj8)コマンドは、現在のメソッドの完全な呼び出しスタックを表示します。1つのメソッドが呼ばれることはわかっていても、どのコードパスが実行されるのか、いつそのメソッドが呼ばれるのかについては全くわからないことがよくあります。これがスタックコマンドの目的です。これはtraceのような構文で、フィルタリングもサポートしており、例として[コスト](https://arthas.aliyun.com/doc/en/stack.html?spm=a2c65.11461447.0.0.26773774iloTj8#filtering-by-cost)をミリ秒単位で表示します。

通常、コマンドラインインターフェースで方向矢印(左、右、上、下)を押すと、以前に実行したコマンドのリストをスクロールします。

`shutdown` コマンドは Arthas サーバーを完全にシャットダウンしてコンソールを終了するために使用されます。

#ArthasのWebコンソール
Arthasを操作するための最もポピュラーな方法の一つは、この記事で紹介してきたようにターミナルコマンドを使って操作することです。しかし、Arthasを操作するもう一つの方法は、もちろんブラウザのWebコンソールを使うことです。

ArthasのWebコンソールはWebソケットを使ってArthasのサーバーと通信し、`http://server_ip_address:8563/` でアクセスすることができます。ローカルにデプロイした場合、アドレスは127.0.0.0.1になります。

ウェブインターフェースは以下のようになっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/1937ef38-2ef4-2ec6-0865-b4259cb331e9.png)


ウェブコンソールのトップメニューから、サーバーのIPアドレスとポートを記入するだけで、他のArthasサーバーに接続できることがわかります。後日、さらに調査することで、より安全性の高いものにすることができます。

#まとめ
この記事では、Arthasのインストール方法や起動方法など、Arthasについて詳しく説明しています。また、Arthasのコマンドラインインターフェースを使ってJVMスレッドを診断するためのコマンドを実行する方法についても学びました。

*アリババクラウドは日本に２つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
[アリババクラウドジャパン公式ページ](https://www.alibabacloud.com/ja)*