実装されたクライアントをワーカースレッドで使用する - AWS X-Ray

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

実装されたクライアントをワーカースレッドで使用する

Scorekeep は、ユーザーがゲームに勝利したときにワーカースレッドを使用して Amazon SNS に通知を発行します。通知の発行は、残りのリクエスト操作の組み合わせよりも時間がかかり、クライアントまたはユーザーには影響しません。したがって、タスクを非同期で実行することは、応答時間を改善するための良い方法です。

ただし、X-Ray SDK for Java は、スレッドが作成されたときにどのセグメントがアクティブであったかを認識しません。結果として、実装された AWS SDK for Java クライアントをスレッド内で使用しようとすると、SegmentNotFoundException がスローされ、スレッドがクラッシュします。

例 web-1.error.log
Exception in thread "Thread-2" com.amazonaws.xray.exceptions.SegmentNotFoundException: Failed to begin subsegment named 'AmazonSNS': segment cannot be found. at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ...

この問題を解決するために、アプリケーションは GetTraceEntity を使用してメインスレッドのセグメントへの参照を取得し、Entity.run() を使用してセグメントのコンテキストにアクセスし、ワーカースレッドコードを安全に実行します。

src/main/java/scorekeep/MoveFactory.java – ワーカースレッドにトレースコンテキストを渡す
import com.amazonaws.xray.AWSXRay; import com.amazonaws.xray.AWSXRayRecorder; import com.amazonaws.xray.entities.Entity; import com.amazonaws.xray.entities.Segment; import com.amazonaws.xray.entities.Subsegment; ... Entity segment = recorder.getTraceEntity(); Thread comm = new Thread() { public void run() { segment.run(() -> { Subsegment subsegment = AWSXRay.beginSubsegment("## Send notification"); Sns.sendNotification("Scorekeep game completed", "Winner: " + userId); AWSXRay.endSubsegment(); } }

Amazon SNS の呼び出しの前に要求が解決されるため、アプリケーションはスレッド用に別のサブセグメントを作成します。これにより、Amazon SNS からの応答を記録する前に X-Ray SDK がセグメントを閉じるのを防ぎます。Scorekeep がリクエストを解決したときにサブセグメントが開いていない場合、Amazon SNS からの応答は失われる可能性があります。

非同期スレッドサブセグメントによるトレース概要。

マルチスレッドの詳細については、「マルチスレッドアプリケーションでのスレッド間のセグメントコンテキストの受け渡し」を参照してください。