在工作线程中使用分析过的客户端 - AWS X-Ray
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

在工作线程中使用分析过的客户端

当用户在游戏中获胜后,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 来获取对主线程中的分段的引用,并获取 SetTraceEntity 以将分段传递回工作线程中的记录器。

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() { recorder.setTraceEntity(segment); Subsegment subsegment = AWSXRay.beginSubsegment("## Send notification"); Sns.sendNotification("Scorekeep game completed", "Winner: " + userId); AWSXRay.endSubsegment(); }

现在,由于请求在对 Amazon SNS 的调用前已解析,应用程序会为线程创建一个单独的子分段。这可以防止 X-Ray 开发工具包在记录来自 Amazon SNS 的响应之前关闭分段。如果在 Scorekeep 解析请求时未打开任何子分段,来自 Amazon SNS 的响应可能会丢失。


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

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