New Relic for Java には、非同期アクティビティのカスタムインスツルメンテーションのための APIメソッドのセット が含まれています。これは サポートされていないフレームワーク の非同期アクティビティをインストルメンテーションする際に最も有用ですが、サポートされているフレームワークにインストルメンテーションを追加するためにAPIを使用することもできます。このドキュメントでは、非同期アクティビティがどのように発生するか、そしてNew Relicがどのように非同期作業をモニタリングするかを説明します。
非同期の操作
同期型の プログラミングモデルでは、プログラミングタスクは通常、特定の順序で実行されます。あるタスクが完了すると次のタスクが開始され、各タスクは次のタスクの完了を阻止します。
非同期 プログラミングでは、ノンブロッキングモデルを採用しているため、タスクを並行して実行することができます。非同期に実行されたタスクは、その実行と初期化において、お互いに完全に独立しています。非同期のコードは特定の順序で実行されないため、サーバーの処理能力を最大限に活用でき、アプリのスループットが向上します。
非同期とスレッドスイッチ
非同期処理を使用するアプリケーションでは、 スレッド切り替え プログラムやタスクがあるスレッドから別のスレッドに切り替わることです。このような非同期のインターリーブを理解することで、どのメソッドをインストルメント化すべきかを判断することができます。
以下は、外部リクエストを並行して行うコントローラを使用したメソッドの例です。これらのリクエストは非同期で実行されるため、各リクエストは互いに独立して実行され、 getScoreAsync()
は呼び出されるとすぐに戻ります。これにより、 getScoreAsync()
が外部呼び出しを行って応答を送信している間、要求スレッドは要求を作成し続けることができます。
@ResponseBody@RequestMapping("getScores", method = RequestMethod.Get produces = “text/plain”)public String getCreditScores(@RequestParam(name = "uids") uids) { return Arrays.stream(uids.split(",")) .parallel() .map(Integer::valueOf) .map(uid -> getScoreAsync(uid)) .collect(Collectors.toList());}
これらのリクエストの中には、他のリクエストよりも先に終了するものもあります。中には、リクエストしたスレッドが他のタスクに移った後に終了するものもあります。
の中に UI、トレースの詳細のウォーターフォール ビューで、UI は非同期アクティビティを水平 x 軸に重なって表示します。
非同期と応答時間
応答時間 は、要求者の視点から見たトランザクションの持続時間として定義されます。非同期アプリケーションの場合、レスポンスタイムはトランザクションの総時間よりも短いことが多いです。これは、メソッドがリターンする前に、先行するすべてのメソッドの完了を待つ必要がないためです。タスクを延期することができるので、アプリケーションは限られたリソースを活用して、より迅速に物事を処理することができます。
チャートのレスポンスタイムラインは、ウェブトランザクションの合計時間よりも、アプリケーションの認知された動作と速度についてより多くの洞察を与えてくれます。
one.newrelic.com > APM & サービス > (アプリを選択) > 概要: APM概要ページで、Java アプリの非同期アクティビティにより、応答時間 (青い線) が合計トランザクション時間よりも短くなる場合があります。これは、メソッドが戻る前に、先行するすべてのメソッドが完了するのを待つ必要がないためです。
非同期APIによるカスタムインストルメント
非同期作業のカスタム・インスツルメンテーションを実装するには、 Javaエージェント非同期APIガイド を参照してください。Java エージェント API の使用方法に関する一般的な情報については、 Java エージェント API ガイド を参照してください。