New Relic for Java には、非同期アクティビティのカスタムインストゥルメンテーション用の一連の API メソッドが含まれています。 これは、 サポートされていないフレームワークでインストゥルメントが行われた非同期アクティビティに最も役立ちますが、API を使用して、サポートされているフレームワークにインストゥルメントを追加することもできます。 このドキュメントでは、非同期アクティビティがどのように発生するか、および New Relic モニターの非同期の動作について説明します。
非同期の操作
synchronousプログラミング モデルでは、プログラミング タスクは通常、特定の順序で実行されます。 次のタスクを開始する前に 1 つのタスクを完了する必要があり、各タスクは次のタスクの完了をブロックします。
Asynchronous プログラミングでは非ブロッキング モデルを使用するため、タスクを並列に実行できます。 非同期に実行されるタスクは、実行と初期化において互いに完全に独立しています。 非同期コードは特定の順序で実行されないため、サーバーの全処理能力をより効率的に使用でき、アプリのスループットが向上します。
非同期とスレッドスイッチ
非同期処理を使用するアプリケーションの場合、 thread-switchingプログラムまたはタスクが 1 つのスレッドから別のスレッドに切り替わるときです。 これらの非同期インターリーブを理解することで、どのメソッドをインストゥルメントする必要があるかを判断するのに役立ちます。
以下は、外部リクエストを並行して行うコントローラを使用したメソッドの例です。これらのリクエストは非同期で実行されるため、各リクエストは互いに独立して実行され、 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 軸に重なって表示します。
非同期と応答時間
Response time リクエスト者の観点から見たトランザクションの期間として定義されます。 非同期アプリケーションの場合、レスポンス時間は合計レスポンス時間よりも短くなることがよくあります。 これは、メソッドが戻る前に、先行するすべてのメソッドが完了するのを待つ必要がないためです。 タスクを延期できるため、アプリケーションは限られたリソースを活用して、より迅速に処理することができます。
チャートのレスポンスタイムラインは、ウェブトランザクションの合計時間よりも、アプリケーションの認知された動作と速度についてより多くの洞察を与えてくれます。
one.newrelic.com > All capabilities > APM & services > (select an app) > Summary: APM Summary ページで、Java アプリの非同期アクティビティにより、レスポンス時間 (青い線) が合計レスポンス時間よりも短くなる場合があります。 これは、メソッドが戻る前に、先行するすべてのメソッドが完了するのを待つ必要がないためです。
非同期APIによるカスタムインストルメント
非同期作業のカスタム・インスツルメンテーションを実装するには、 Javaエージェント非同期APIガイド を参照してください。Java エージェント API の使用方法に関する一般的な情報については、 Java エージェント API ガイド を参照してください。