在工作线程中使用检测的客户端 - Amazon X-Ray
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

在工作线程中使用检测的客户端

当用户在游戏中获胜后,Scorekeep 使用工作线程向 Amazon SNS 发布通知。发布通知的时间会比请求操作其余部分的总时间更长,并且不会影响客户端或用户。因此,以异步方式执行任务是一种改进响应时间的好方法。

但是,在创建线程时,适用于 Java 的 X-Ray 开发工具包不知道哪个分段处于活动状态。因此,当您尝试在线程中使用检测的Amazon 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 的调用前已解析,应用程序会为线程创建一个单独的子分段。这可以防止 X-Ray 开发工具包在记录来自 Amazon SNS 的响应之前关闭分段。如果在 Scorekeep 解析请求时未打开任何子分段,来自 Amazon SNS 的响应可能会丢失。


      使用异步线程子分段的跟踪概述。

有关多线程处理的更多信息,请参阅在多线程应用程序中的线程之间传递分段上下文