Application Real-Time Monitoring Service(ARMS)のコード診断機能は、継続的プロファイリング技術を使用して、スレッドのメソッドスタックスナップショットを定期的に収集し、コード実行をシミュレートします。
シナリオ
プロモーションで低速呼び出しが発生した場合、コード診断機能は問題のあるコードをすばやく特定できます。
システムで多数の低速呼び出しが発生した場合、この機能は問題のあるコードを自動的に保存できます。
ビジネスが複雑すぎて、時折発生する低速呼び出しを再現できない場合、この機能はコードの実行とメソッドの呼び出しをシミュレートできます。
トレースにフレームワーク以外のレイヤーのメソッドとインストルメンテーションが欠落している場合、この機能は、インストルメンテーションに関連するメソッドに費やされた時間を復元するのに役立ちます。
前提条件
ARMS エージェントのバージョンは 3.1.4 以降です。
オペレーティングシステムカーネルと JDK のバージョンは要件を満たしています。コード診断機能は、継続的プロファイリング技術に依存しています。詳細については、「継続的プロファイリング機能を使用する」をご参照ください。
同期トレースのみがコード診断機能をサポートしています。非同期トレースはサポートしていません。
コード診断機能を有効にする
ARMS console にログインします。左側のナビゲーションペインで、 を選択します。
[アプリケーションリスト] ページで、上部のナビゲーションバーでリージョンを選択し、管理するアプリケーションの名前をクリックします。
説明[言語] 列に表示されるアイコンは、アプリケーションが記述されている言語を示します。
: Java アプリケーション
: Go アプリケーション
: Python アプリケーション
ハイフン (-): Managed Service for OpenTelemetry で監視されるアプリケーション。
左側のナビゲーションペインで、[アプリケーション設定] をクリックします。表示されるページで、[カスタム設定] タブをクリックします。
[継続的プロファイリング] セクションで、[メインスイッチ] と [コードホットスポット] をオンにして、アプリケーションインスタンスの IP アドレスまたは複数のインスタンスの CIDR ブロックを構成します。
重要ARMS エージェント V4.2.x 以降では、この機能はデフォルトで有効になっています。以前のバージョンの ARMS エージェントでは、この機能が設定されていないアプリケーションに対してコンソールで有効として表示されますが、[保存] をクリックした後にのみ有効になります。
タブの下部にある [保存] をクリックします。
変更は、アプリケーションを再起動しなくても有効になります。
[インターフェース呼び出し] ページでホットスポットコードデータを表示する
例:JSON データを解析およびトラバースし、ダウンストリーム HTTP インターフェースを呼び出します。
public class HotSpotAction extends AbsAction {
private RestTemplate restTemplate = new RestTemplate();
// リクエストメソッド。
@Override
public void runBusiness() {
readFile();
invokeAPI();
}
// HTTP 呼び出しを実行します。
private void invokeAPI() {
String url = "https://httpbin.org/get";
String response = restTemplate.getForObject(url, String.class);
}
// ファイルデータを読み取って解析します。
private double readFile() {
InputStreamReader reader = new InputStreamReader(
ClassLoader.getSystemResourceAsStream("data/xxx.json"));
LinkedList<Movie> movieList = GSON.fromJson(reader, new TypeToken<LinkedList<Movie>>() {
}.getType());
double totalCount = 0;
for (int i = 0; i < movieList.size(); i++) {
totalCount += movieList.get(i).rating();
}
return totalCount;
}
}
ARMS console にログインします。左側のナビゲーションペインで、 を選択します。
[アプリケーションリスト] ページで、上部のナビゲーションバーでリージョンを選択し、管理するアプリケーションの名前をクリックします。
説明[言語] 列に表示されるアイコンは、アプリケーションが記述されている言語を示します。
: Java アプリケーション
: Go アプリケーション
: Python アプリケーション
ハイフン (-): Managed Service for OpenTelemetry で監視されるアプリケーション。
左側のナビゲーションペインで、[インターフェース呼び出し] をクリックします。表示されるページで、インターフェースを選択し、[インターフェーススナップショット] タブをクリックします。
[インターフェーススナップショット] タブで、トレース ID をクリックします。
[詳細] 列の虫眼鏡アイコンをクリックし、[コードホットスポット] タブをクリックします。
図の左側は、関係するすべてのメソッドに費やされた時間を示し、右側は、各メソッドのすべてのメソッドスタック情報のフレームグラフを示しています。
[Self] 列には、スタック内の各メソッドが消費する時間またはリソースが表示されます。子メソッドが消費する時間またはリソースは含まれません。このデータを使用して、過剰な時間またはリソースを費やしているメソッドを特定できます。
[Total] 列には、各メソッドによって消費された時間またはリソースが表示されます。すべての子メソッドによって消費された時間も含まれます。このデータを使用して、最も多くの時間またはリソースを費やしているメソッドを特定できます。
コードロジックを分析する場合、[Self] 列または右側フレームグラフの下部にある幅の広いフレームに注目することで、時間のかかるメソッドを見つけることができます。一般に、幅の広いフレームは、システムパフォーマンスのボトルネックを示します。前の図の java.lang.Thread.sleep() メソッドは、システムパフォーマンスのボトルネックが原因で多くの時間を消費しています。
前の図に基づいて、次の分析を実行します。
[Self] 列の値を昇順に並べ替えます。最大値を持つメソッド java.util.LinkedList.node(int) を見つけてクリックします。関連するメソッドがフレームグラフに表示されます。
java.util.LinkedList.node(int) メソッドは、フレームグラフのスタックトップで最も幅の広いボックスを持っていることに注意してください。
java.util.LinkedList.node(int) メソッドは Java Development Kit(JDK)のライブラリ関数であるため、さらに上を検索すると、java.util.LinkedList.get(int) メソッドとその親メソッド com.alibaba.cloud.pressure.memory.HotSpotAction.readFile() が見つかります。アプリケーションによって定義された最初のサービスメソッドとして、com.alibaba.cloud.pressure.memory.HotSpotAction.readFile() メソッドは 3.75 秒を消費し、スタックの 69.88% を占めています。したがって、com.alibaba.cloud.pressure.memory.HotSpotAction.readFile() メソッドは、指定された期間に多くのリソースを消費していると結論付けることができます。ここで説明したメソッドを使用して、関連メソッドのロジックを分析し、最適化できるかどうかを確認できます。
よくある質問
コードに費やされた時間がリクエストに費やされた時間よりも短いのはなぜですか?
コード診断機能がアプリケーションのパフォーマンスに与える影響を最小限に抑えるため、データ収集を最適化しました。このようにして、表示される時間は実際の時間よりも短くなります。一般に、偏差は 20 ミリ秒以下です。絶対値の偏差は無視し、最も時間がかかるメソッドに焦点を当てることをお勧めします。
コード診断の統計には制限がありますか?
15 分以上かかるリクエストの場合、コード診断機能は最初の 15 分間の分析データのみを提供します。
システムのオーバーヘッドを削減するため、アプリケーション監視は 500 ミリ秒未満のリクエストからコードデータを収集しません。したがって、[ホットスポットコード] タブにデータが表示されない場合があります。