

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

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

**注意**  
X-Ray SDK/Daemon 维护通知 — 2026 年 2 月 25 日， Amazon X-Ray SDKs/Daemon 将进入维护模式，在该模式下，X-Ray SDK 和 Daemon 的发布 Amazon 将仅限于解决安全问题。有关支持时间表的更多信息，请参阅 [X-Ray SDK 和 Daemon Support 时间表](xray-sdk-daemon-timeline.md)。我们建议迁移到 OpenTelemetry。有关迁移到的更多信息 OpenTelemetry，请参阅[从 X-Ray 仪器迁移到 OpenTelemetry 仪器](https://docs.amazonaws.cn/xray/latest/devguide/xray-sdk-migration.html)。

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

要管理子分段，请使用 `beginSubsegment` 和 `endSubsegment` 方法。

**Example GameModel.java-自定义子细分**  

```
import [com.amazonaws.xray.AWSXRay](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRay.html);
...
  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 加载游戏会话，并使用的 Dynam 适用于 Java 的 Amazon SDK oDB 映射器保存游戏。在子分段中包装此代码将调用控制台跟踪视图中 `Save Game` 子分段的 DynamoDB 子项。

![\[Timeline showing Scorekeep and DynamoDB operations with durations and status checks.\]](http://docs.amazonaws.cn/xray/latest/devguide/images/scorekeep-PUTrules-timeline-subsegments.png)


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

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

**Example 子分段 Lambda 函数**  

```
import [com.amazonaws.xray.AWSXRay](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRay.html);

AWSXRay.createSubsegment("getMovies", (subsegment) -> {
    // function code
});
```

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

**Example 包含元数据的子分段**  

```
"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 进程守护程序。

**Example 异步子分段**  

```
@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();
}
```