会社で障害問題を特定する際、一般的にはコード内の重要な部分にログを出力し、環境コンテナ内で Jar パッケージを交換する形式で問題の特定分析を行います。しかし、このような問題の特定プロセスは非常に面倒です:
- まず、ログ出力の網羅性を確保する必要があります。万が一、重要な情報が出力されていない場合は、再度ログを出力し、パッケージを交換し、サービスを再起動する必要があり、一連のプロセスで多くの時間を浪費します;
- 次に、すべての環境でパッケージの交換やサービスの再起動が実行できるわけではありません。
そのため、最近はより良い障害問題の特定方法を探しており、阿里が開発したオープンソースの Java サービス診断ツールがなかなか良さそうだと気付きました。このツールは、メソッド呼び出しの引数、戻り値、呼び出された呼び出しパス、呼び出し時間、メソッド呼び出し回数、成功回数、失敗回数などを記録できるため、学習して記録しておきます。
arthas とは#
公式紹介:
Arthas は、オンライン監視診断製品で、グローバルな視点からアプリケーションのロード、メモリ、GC、スレッドの状態情報をリアルタイムで確認でき、アプリケーションコードを変更することなく、ビジネス問題を診断できます。これには、メソッド呼び出しの引数、例外の確認、メソッド実行時間の監視、クラスロード情報などが含まれ、オンライン問題のトラブルシューティング効率を大幅に向上させます。
実行環境#
- JDK 6 以上の環境のみサポート
- Java で書かれており、クロスプラットフォームをサポート:Linux(主に)、Mac、Windows
特徴#
- コマンドラインインタラクティブモードを採用
Tab
キーによる自動補完機能を提供
初歩的な使用#
会社で使用している環境は主にコンテナ内にあるため、以下では Linux 環境でこのツールをどのように使用するかを主に記録します。
使用パッケージのダウンロード#
会社の環境は内部ネットワーク環境で、直接 Github にアクセスしてインストールパッケージをダウンロードすることができないため、マシンのネットワーク問題でダウンロードできないのを防ぐために、手動で Github からダウンロードし、サービスコンテナ内にコピーして使用します。
Github から完全なインストールパッケージをダウンロードします。ダウンロードリンク:https://github.com/alibaba/arthas/releases
コンテナ環境での解凍#
アンインストール#
問題を特定した後は戦場をきれいにする必要があるため、このツールのアンインストール方法も記録しておきます。
以下の 3 つのステップを実行することでツールをアンインストールできます。
実行#
まず、停止しない Java プログラムサービスを起動します。公式のインストールパッケージには、練習用の Jar パッケージ
math-game.jar
が付属しています(ただし、一般的に私たちのサービスも常に実行されていますので、ここでは公式のパッケージを記録として使用します)。
次に、arthas を起動します。
よく使うコマンド#
help#
dashboard#
ダッシュボード:現在のシステムのリアルタイムデータパネルを表示します。普段このダッシュボードがないときは、一般的に Linux に付属の
top
コマンドを使用してシステムの実行情報を確認します。
dashboardを入力し、Enter
を押すと、現在のプロセスの情報が表示されます。ctrl+c
を押すか、q
を入力すると実行を中断できます。
表示される情報は大きく 3 つのブロックに分かれています:
- 一番上はスレッド関連の情報
- 中間の領域は JVM メモリ関連の情報
- 一番下は Java の実行環境情報
具体的な各列の情報については公式文書を参照してください。
thread#
現在のスレッド情報スタックを確認します。
パラメータがない場合、最初のページのスレッド情報を表示します。#
デフォルトでは CPU 増分時間の降順で並べ替えられ、最初のページのデータのみが表示されます。
現在最も忙しい上位 N 個のスレッドを一度に表示し、スタックを印刷します。#
thread --all、すべての一致するスレッドを表示します。#
thread id、指定されたスレッドの実行スタックを表示します。#
thread -b、現在他のスレッドをブロックしているスレッドを見つけます。#
watch#
指定されたメソッドの呼び出し状況を観察します。
観察できる内容:
メソッドの戻り値、引数、メソッドがスローした例外、OGNL 式を記述することで対応する変数の確認も可能です。
関数呼び出しの戻り時の引数、this オブジェクト、戻り値を観察します。#
関数呼び出し前と関数戻り後を同時に観察します。#
現在のオブジェクト内の属性を観察します。#
関数の実行前後に現在のオブジェクト内の属性を確認したい場合は、target キーワードを使用します。target は現在のオブジェクトを示し、target.field_name を使用して現在のオブジェクトの特定の属性にアクセスします。
trace#
メソッド内部の呼び出しパスを表示し、パス上の各ノードでの時間を出力します。サービス間の呼び出し時間が長すぎる場合に使用します。
- 出力結果の #24 は、ソースファイルの 24 行目で
primeFactors()
関数が呼び出されたことを示します。 - 出力結果の #25 は、ソースファイルの 25 行目で
print()
関数が呼び出されたことを示します。
stack#
現在のメソッドが呼び出された呼び出しパスを出力します。このメソッド(多くの場所から呼び出されている)をどこから実行したかを知りたい場合にこのコマンドを使用します(根源を探るのに適しています)。
jad#
指定されたロード済みクラスのソースコードを逆コンパイルし、オンラインでビジネスロジックを理解しやすくします。逆コンパイルされたコードは構文ハイライト付きです。