本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
在工作者執行緒中使用受檢測用戶端
Scoreis 會使用工作者執行事,在使用者贏得遊戲時發佈通知到 Amazon SNS。發佈通知所花費的時間比其餘合併的請求操作更長,但不會影響用戶端或使用者。因此,若要改善回應時間,以非同步方式執行任務是一種好方法。
不過,適用於 Java 的 X-Ray 開發套件並不知道在執行建立時哪個區段為作用中。因此,當您嘗試在執行緒內使用經檢測的 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();
}
}
由於在呼叫之前已解析請求,因此應用程式會為執行問題建立獨立的子區段。這可防止 X-Ray 開發套件在記錄 Amazon SNS 的回應之前結束區段。如果 Amazon SNS corenow 解析請求時沒有任何子區段開啟,可能會遺失的回應。
![使用非同步執行緒子區段的追蹤概觀。](images/scorekeep-workerthread.png)
如需多執行緒的詳細資訊,請參閱在多執行緒應用程式之間傳遞區段內容。