使用适用于 Java 的 X-Ray 开发工具包生成自定义子分段 - AWS X-Ray

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

使用适用于 Java 的 X-Ray 开发工具包生成自定义子分段

子分段可为跟踪的分段扩展为了给请求提供服务而已完成的工作的详细信息。每次使用已检测的客户端进行调用时,X-Ray 开发工具包在子分段中记录生成的信息。您可以创建其他子分段来分组其他子分段,来度量某个代码段的性能如何,或是来记录注释和元数据。

要管理子分段,请使用 beginSubsegmentendSubsegment 方法。

例 GameModel.java - 自定义子分段
import com.amazonaws.xray.AWSXRay; ... public void saveGame(Game game) throws SessionNotFoundException { // wrap in subsegment Subsegment subsegment = AWSXRay.beginSubsegment("Save Game"); try { // check session String sessionId = game.getSession(); if (sessionModel.loadSession(sessionId) == null ) { throw new SessionNotFoundException(sessionId); } mapper.save(game); } catch (Exception e) { subsegment.addException(e); throw e; } finally { AWSXRay.endSubsegment(); } }

在此示例中,子分段中的代码使用会话模型上的方法从 DynamoDB 加载游戏会话,并使用 AWS SDK for Java 的 DynamoDB 映射器保存游戏。在子分段中包装此代码将调用控制台跟踪视图中 Save Game 子分段的 DynamoDB 子项。

Timeline showing Scorekeep and DynamoDB operations with durations and status checks.

如果子分段中的代码引发了检查异常,将其包装在 try 代码块中并在 AWSXRay.endSubsegment() 代码块中调用 finally 以确保始终结束子分段。如果子分段未结束,则父分段无法完成,不发送到 X-Ray。

对于未引发检查异常的代码,可以将代码传递到 AWSXRay.CreateSubsegment 作为 lambda 函数。

例 子分段 Lambda 函数
import com.amazonaws.xray.AWSXRay; AWSXRay.createSubsegment("getMovies", (subsegment) -> { // function code });

当您在分段或者其他子分段中创建子分段时,适用于 Java 的 X-Ray 开发工具包将为其生成 ID 并记录开始时间和结束时间。

例 包含元数据的子分段
"subsegments": [{ "id": "6f1605cd8a07cb70", "start_time": 1.480305974194E9, "end_time": 1.4803059742E9, "name": "Custom subsegment for UserModel.saveUser function", "metadata": { "debug": { "test": "Metadata string from UserModel.saveUser" } },

对于异步和多线程编程,必须手动将子分段传递给 endSubsegment() 方法以确保其正确关闭,因为在异常执行期间可能会修改 X-Ray 上下文。如果异步子分段在其父分段之前关闭,则此方法将会自动整个分段流式传输到 X-Ray 进程守护程序。

例 异步子分段
@GetMapping("/api") public ResponseEntity<?> api() { CompletableFuture.runAsync(() -> { Subsegment subsegment = AWSXRay.beginSubsegment("Async Work"); try { Thread.sleep(3000); } catch (InterruptedException e) { subsegment.addException(e); throw e; } finally { AWSXRay.endSubsegment(subsegment); } }); return ResponseEntity.ok().build(); }