

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

# Amazon X-Ray 适用于 Java 的 SDK
适用 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)。

X-Ray SDK for Java 是一组面向 Java Web 应用程序的库，可提供类和方法来生成跟踪数据并将跟踪数据发送给 X-Ray 进程守护程序。跟踪数据包括有关应用程序处理的传入 HTTP 请求的信息，以及应用程序使用 Amazon SDK、HTTP 客户端或 SQL 数据库连接器对下游服务进行的调用的信息。您还可以手动创建分段并在注释和元数据中添加调试信息。

X-Ray SDK for Java 是一个开源项目。你可以关注该项目并在 [github 上 GitHub提交议题和拉取请求。 com/aws/aws](https://github.com/aws/aws-xray-sdk-java)-xray-sdk-java

首先通过[添加`AWSXRayServletFilter` 作为 servlet 筛选器](xray-sdk-java-filters.md)来跟踪传入请求。servlet 筛选器会创建[分段](xray-concepts.md#xray-concepts-segments)。当分段打开时，您可以使用开发工具包客户端的方法将信息添加到分段，并创建子分段以跟踪下游调用。开发工具包还会自动记录在分段打开时应用程序引发的异常。

从版本 1.3 开始，您可以使用 [Spring 中的面向方面的编程 (AOP)](xray-sdk-java-aop-spring.md) 来检测应用程序。这意味着你可以在应用程序运行时对其进行检测，而无需在 Amazon应用程序的运行时中添加任何代码。

接下来，使用适用于 Java 的 X-Ray SDK，在构建配置中包[含 SDK Instrumentor 子模块](#xray-sdk-java-dependencies)，对 适用于 Java 的 Amazon SDK 客户进行检测。每当您使用已检测的客户端调用下游 Amazon Web Services 服务 或资源时，SDK 都会在子分段中记录有关该调用的信息。 Amazon Web Services 服务 您在服务中访问的资源将作为下游节点显示在跟踪地图上，以帮助您识别各个连接上的错误和限制问题。

如果您不想检测所有下游调用 Amazon Web Services 服务，则可以省略 Instrumentor 子模块，然后选择要检测的客户端。通过[向 Amazon SDK 服务客户端添加`TracingHandler`](xray-sdk-java-awssdkclients.md)来检测各个客户端。

其他 X-Ray SDK for Java 子模块为对 HTTP Web APIs 和 SQL 数据库的下游调用提供了工具。您可以[使用 X-Ray SDK for Java 的 `HTTPClient` 版本和 Apache HTTP 子模块中的 `HTTPClientBuilder`](xray-sdk-java-httpclients.md) 来检测 Apache HTTP 客户端。要检测 SQL 查询，请[将 SDK 的拦截程序添加到数据源](xray-sdk-java-sqlclients.md)。

在开始使用 SDK 后，通过[配置记录器和 servlet 筛选器](xray-sdk-java-configuration.md)来自定义其行为。您可以添加插件来记录有关应用程序上运行的计算资源的数据，通过定义采样规则来自定义采样行为，设置日志级别以在应用程序日志中查看来自开发工具包的更多或更少的信息。

记录有关请求以及应用程序在[注释和元数据](xray-sdk-java-segment.md)中所做的工作的其他信息。注释是简单的键值对，已为这些键值对编制索引以用于[筛选条件表达式](xray-console-filters.md)，以便您能够搜索包含特定数据的跟踪。元数据条目的限制性较低，并且可以记录整个对象和数组 - 可序列化为 JSON 的任何项目。

**注释和元数据**  
注释和元数据是您使用 X-Ray 开发工具包添加到分段的任意文本。系统会对注释编制索引，以便与筛选表达式一起使用。元数据未编制索引，但可以使用 X-Ray 控制台或 API 在原始分段中查看。您授予 X-Ray 读取权限的任何人都可以查看这些数据。

当代码中具有大量检测的客户端时，一个请求分段可包含许多子分段，检测的客户端发起的每个调用均对应一个子分段。您可以通过将客户端调用包含在[自定义子分段](xray-sdk-java-subsegments.md)中来整理子分段并为其分组。您可以为整个函数或任何代码部分创建自定义子分段，并记录子分段的元数据和注释，而不是编写父分段的所有内容。

## 子模块


您可以从 Maven 下载 X-Ray SDK for Java。X-Ray SDK for Java 按使用案例被拆分为子模块，其中的材料清单用于版本管理：
+ [https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-core/](https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-core/)（必需） - 用于创建分段和传输分段的基本功能。包括 `AWSXRayServletFilter` 用于检测传入请求。
+ [https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-aws-sdk/](https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-aws-sdk/)— 通过添加跟踪 适用于 Java 的 Amazon SDK 客户端作为请求处理程序，对客户端发 Amazon Web Services 服务 出的调用进行监测。
+ [https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-aws-sdk-v2/](https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-aws-sdk-v2/)— 通过添加跟踪客户端作为请求拦截器，对 Amazon Web Services 服务 使用 适用于 Java 的 Amazon SDK 2.2 及更高版本的客户端进行的调用进行监测。
+ [https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-aws-sdk-instrumentor/](https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-aws-sdk-instrumentor/)— 使用`aws-xray-recorder-sdk-aws-sdk`，自动对所有 适用于 Java 的 Amazon SDK 客户进行仪器。
+ [https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-aws-sdk-v2-instrumentor/](https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-aws-sdk-v2-instrumentor/)— 使用`aws-xray-recorder-sdk-aws-sdk-v2`，自动检测所有 适用于 Java 的 Amazon SDK 2.2 及更高版本的客户端。
+ [https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-apache-http/](https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-apache-http/) - 检测使用 Apache HTTP 客户端进行的传出 HTTP 调用。
+  [https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-spring/](https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-spring/) - 为 Spring AOP 框架应用程序提供拦截程序。
+ [https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-sql-postgres/](https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-sql-postgres/) - 检测由 JDBC 对 PostgreSQL 数据库进行的传出调用。
+ [https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-sql-mysql/](https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-sql-mysql/) - 检测由 JDBC 对 MySQL 数据库进行的传出调用。
+ [https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-bom/](https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-bom/) - 提供材料清单，您可以用它来指定用于所有子模块的版本。
+  [https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-metrics/](https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-metrics/)— 从您收集的 X-Ray 细分中发布未抽样的亚马逊 CloudWatch 指标。

如果您使用 Maven 或 Gradle 来构建应用程序，可[将 X-Ray SDK for Java 添加到您的构建配置中](#xray-sdk-java-dependencies)。

有关 SDK 的类和方法的参考文档，请参阅[Amazon X-Ray SDK for Java API 参考](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc)。

## 要求


适用于 Java 的 X-Ray SDK 需要 Java 8 或更高版本、Servlet API 3、 Amazon SDK 和 Jackson。

该 SDK 在编译和运行时依赖于以下库：
+ Amazon 适用于 Java 的 SDK 版本 1.11.398 或更高版本
+ Servlet API 3.1.0

这些依赖项在 SDK 的 `pom.xml` 文件中声明，如果您使用 Maven 或 Gradle 生成则自动包括在内。

如果您使用包括在 X-Ray SDK for Java 中的库，则必须使用包括的版本。例如，如果您在运行时已经依赖于 Jackson 并在部署中为该依赖项包括了 JAR 文件，则必须删除这些 JAR 文件，因为 SDK JAR 包括其自己的 Jackson 库版本。

## 依赖关系管理


可从 Maven 获得 X-Ray SDK for Java：
+ **组** – `com.amazonaws`
+ **构件** – `aws-xray-recorder-sdk-bom`
+ **版本**：`2.11.0`

如果您使用 Maven 来生成应用程序，则在 `pom.xml` 文件中添加 SDK 作为依赖项。

**Example pom.xml - 依赖项**  

```
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>com.amazonaws</groupId>
      <artifactId>aws-xray-recorder-sdk-bom</artifactId>
      <version>2.11.0</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>
<dependencies>
  <dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-xray-recorder-sdk-core</artifactId>
  </dependency>
  <dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-xray-recorder-sdk-apache-http</artifactId>
  </dependency>
  <dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-xray-recorder-sdk-aws-sdk</artifactId>
  </dependency>
  <dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-xray-recorder-sdk-aws-sdk-instrumentor</artifactId>
  </dependency>
  <dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-xray-recorder-sdk-sql-postgres</artifactId>
  </dependency>
  <dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-xray-recorder-sdk-sql-mysql</artifactId>
  </dependency>
</dependencies>
```

对于 Gradle，添加 SDK 作为 `build.gradle` 文件中的编译时依赖项。

**Example build.gradle - 依赖项**  

```
dependencies {
  compile("org.springframework.boot:spring-boot-starter-web")
  testCompile("org.springframework.boot:spring-boot-starter-test")
  compile("com.amazonaws:aws-java-sdk-dynamodb")
  compile("com.amazonaws:aws-xray-recorder-sdk-core")
  compile("com.amazonaws:aws-xray-recorder-sdk-aws-sdk")
  compile("com.amazonaws:aws-xray-recorder-sdk-aws-sdk-instrumentor")
  compile("com.amazonaws:aws-xray-recorder-sdk-apache-http")
  compile("com.amazonaws:aws-xray-recorder-sdk-sql-postgres")
  compile("com.amazonaws:aws-xray-recorder-sdk-sql-mysql")
  testCompile("junit:junit:4.11")
}
dependencyManagement {
    imports {
        mavenBom('com.amazonaws:aws-java-sdk-bom:1.11.39')
        mavenBom('com.amazonaws:aws-xray-recorder-sdk-bom:2.11.0')
    }
}
```

如果您使用 Elastic Beanstalk 来部署应用程序，则可以使用 Maven 或 Gradle 在每次部署时生成 on-instance，而不是生成和上传包括所有依赖项的大档案。有关使用 Gradle 的示例，请参阅[示例应用程序](xray-scorekeep.md)。

# Amazon X-Ray 适用于 Java 的自动检测代理
自动检测代理

**注意**  
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)。

适用于 Java 的 Amazon X-Ray 自动检测代理是一种跟踪解决方案，只需最少的开发工作即可对 Java Web 应用程序进行检测。该代理能够跟踪基于 Servlet 的应用程序，以及使用支持的框架和库发出的该代理所有的下游请求。其中包括下游 Apache HTTP 请求、 Amazon SDK 请求以及使用 JDBC 驱动程序进行的 SQL 查询。该代理跨线程传播 X-Ray 上下文，包括所有活动分段和子分段。Java 代理仍然可以使用 X-Ray SDK 的所有配置和多功能性。选择的都是合适的默认值以确保轻松就可以使用该代理。

X-Ray 代理解决方案最适合基于 Servlet、请求响应 Java Web 应用程序服务器。如果您的应用程序使用异步框架或者不能很好地建模为请求-响应服务，则可能需要考虑改用 SDK 进行手动检测。 

X-Ray 代理是使用分布式系统理解工具包（简称 DiSCo）构建的。Di SCo 是一个开源框架，用于构建可在分布式系统中使用的 Java 代理。虽然使用 X-Ray 代理不需要了解 DiSCo ，但您可以通过访问其[主页](https://github.com/awslabs/disco)来了解有关该项目的更多信息 GitHub。X-Ray 代理也是完全开源的。要查看源代码、做出贡献或提出有关代理的问题，请访问代理[的存储库 GitHub](https://github.com/aws/aws-xray-java-agent)。

## 示例应用程序


该[eb-java-scorekeep](https://github.com/aws-samples/eb-java-scorekeep/tree/xray-agent)示例应用程序适用于使用 X-Ray 代理进行检测。此分支不包含 Servlet 筛选器或记录器配置，因为这些功能由代理完成。若要在本地运行该应用程序或使用 Amazon 资源，请按照示例应用程序的自述文件中列出的步骤操作。关于如何使用示例应用程序生成 X-Ray 跟踪的说明位于[示例应用程序的教程](xray-scorekeep.md)中。

## 开始使用


请按照以下步骤操作，开始在您自己的应用程序中使用 X-Ray 自动检测 Java 代理。

1. 在环境中运行 X-Ray 进程守护程序。有关更多信息，请参阅 [Amazon X-Ray 守护程序](xray-daemon.md)。

1. 下载[代理的最新发行版](https://github.com/aws/aws-xray-java-agent/releases/latest/download/xray-agent.zip)。解压缩存档并记下其在文件系统中的位置。其内容应与以下内容类似。

   ```
   disco 
   ├── disco-java-agent.jar 
   └── disco-plugins 
       ├── aws-xray-agent-plugin.jar 
       ├── disco-java-agent-aws-plugin.jar 
       ├── disco-java-agent-sql-plugin.jar 
       └── disco-java-agent-web-plugin.jar
   ```

1. 修改应用程序的 JVM 参数使其包含以下内容，以启用代理。如适用，请确保将 `-javaagent` 参数放在 `-jar` 参数*之前*。修改 JVM 参数的过程因启动 Java 服务器所使用的工具和框架而异。请参阅服务器框架的文档了解详细指南。

   ```
   -javaagent:/<path-to-disco>/disco-java-agent.jar=pluginPath=/<path-to-disco>/disco-plugins
   ```

1. 设置 `AWS_XRAY_TRACING_NAME` 环境变量或 `com.amazonaws.xray.strategy.tracingName` 系统属性以指定您的应用程序在 X-Ray 控制台上的显示方式。如果未提供名称，则使用默认名称。

1. 重启服务器或容器。现在，会跟踪传入的请求及其下游调用。如果没有看到预期结果，请参阅[问题排查](#XRayAutoInstrumentationAgent-Troubleshooting)。

## 配置


X-Ray 代理由用户提供的外部 JSON 文件进行配置。默认情况下，此文件位于名为“`xray-agent.json`”的用户的类路径的根目录中（例如，在其 `resources` 目录中）。可以将 `com.amazonaws.xray.configFile` 系统属性设置为配置文件的绝对系统文件路径，为配置文件配置自定义位置。

示例配置文件如下所示。

```
{     
    "serviceName": "XRayInstrumentedService", 
    "contextMissingStrategy": "LOG_ERROR", 
    "daemonAddress": "127.0.0.1:2000", 
    "tracingEnabled": true, 
    "samplingStrategy": "CENTRAL",     
    "traceIdInjectionPrefix": "prefix",     
    "samplingRulesManifest": "/path/to/manifest",     
    "awsServiceHandlerManifest": "/path/to/manifest",     
    "awsSdkVersion": 2,     
    "maxStackTraceLength": 50,     
    "streamingThreshold": 100,     
    "traceIdInjection": true,     
    "pluginsEnabled": true,     
    "collectSqlQueries": false 
}
```

### 配置规范


下表介绍了每个属性的有效值。属性名称区分大小写，但它们的键不区分大小写。可以被环境变量和系统属性覆盖的属性，其优先级顺序始终先是环境变量、系统属性，然后再是配置文件。有关您可以覆盖的属性的相关信息，请参阅[环境变量](xray-sdk-java-configuration.md#xray-sdk-java-configuration-envvars)。所有字段都是可选字段。


|  属性名称  |  Type  |  有效值  |  说明  |  环境变量  |  系统属性  |  默认  | 
| --- | --- | --- | --- | --- | --- | --- | 
|  serviceName  |  字符串  |  任何字符串  |  将在 X-Ray 控制台中显示的已检测服务的名称。  |  AWS\$1XRAY\$1TRACING\$1NAME  |  com.amazonaws.xray.strategy.tracingNam  |  XRayInstrumentedService  | 
|  contextMissingStrategy  |  字符串  |  LOG\$1ERROR、IGNORE\$1ERROR  |  代理尝试使用 X-Ray 分段上下文但不存在时所采取的操作。  |  AWS\$1XRAY\$1上下文\$1缺失  |  com.amazonaws.xray.strategy contextMissingStrategy  |  LOG\$1ERROR  | 
|  daemonAddress  |  字符串  |  格式化的 IP 地址和端口，或者 TCP 和 UDP 地址列表  |  代理用于与 X-Ray 进程守护程序通信的地址。  |  AWS\$1XRAY\$1守护进程\$1地址  |  com.amazonaws.xray.emitter.daemonAddress  |  127.0.0.1:2000  | 
|  tracingEnabled  |  布尔值  |  True, False  |  启用 X-Ray 代理进行检测。  |  AWS\$1XRAY\$1追踪\$1已启用  |  com.amazonaws.xray.tracingEnabled  |  TRUE  | 
|  samplingStrategy  |  字符串  |  CENTRAL、LOCAL、NONE、ALL  |  代理使用的采样策略。ALL 捕获所有请求，NONE 不捕获任何请求。请参阅[采样规则](xray-sdk-java-configuration.md#xray-sdk-java-configuration-sampling)。  |  不适用  |  不适用  |  CENTRAL  | 
|  traceIdInjection前缀  |  字符串  |  任何字符串  |  在日志中注入跟踪 IDs 之前包含提供的前缀。  |  不适用  |  不适用  |  无（空字符串）  | 
|  samplingRulesManifest  |  字符串  |  绝对文件路径  |  自定义采样规则文件的路径，该文件用作本地采样策略的采样规则或中心策略的后备规则的来源。  |  不适用  |  不适用  |   [DefaultSamplingRules.json](https://github.com/aws/aws-xray-sdk-java/blob/master/aws-xray-recorder-sdk-core/src/main/resources/com/amazonaws/xray/strategy/sampling/DefaultSamplingRules.json)   | 
|   awsServiceHandler清单   |  字符串  |  绝对文件路径  |  自定义参数允许列表的路径，可从 Amazon SDK 客户端捕获其他信息。  |  不适用  |  不适用  |   [DefaultOperationParameterWhitelist.json](https://github.com/aws/aws-xray-sdk-java/blob/master/aws-xray-recorder-sdk-aws-sdk-v2/src/main/resources/com/amazonaws/xray/interceptors/DefaultOperationParameterWhitelist.json)   | 
|  awsSdkVersion  |  整数  |  1、2  |  您正在使用的 [Amazon SDK for Java](https://docs.amazonaws.cn/sdk-for-java/index.html) 的版本。如果 `awsServiceHandlerManifest` 也没有设置，请会被忽略。  |  不适用  |  不适用  |  2  | 
|  maxStackTrace长度  |  整数  |  非负整数  |  一个跟踪中记录的堆栈跟踪的最大行数。  |  不适用  |  不适用  |  50  | 
|  streamingThreshold  |  整数  |  非负整数  |  至少在关闭这么多子分段之后，它们会被流式传输到守护程序 out-of-band，以避免区块太大。  |  不适用  |  不适用  |  100  | 
|  traceIdInjection  |  布尔值  |  True, False  |  如果还添加了[日志记录配置](xray-sdk-java-configuration.md#xray-sdk-java-configuration-logging)中所述的依赖项和配置，则启用 X-Ray 跟踪 ID 注入日志。否则，不执行任何操作。  |  不适用  |  不适用  |  TRUE  | 
|  pluginsEnabled  |  布尔值  |  True, False  |  启用用于记录有关您正在操作的 Amazon 环境的元数据的插件。请参阅[插件](xray-sdk-java-configuration.md#xray-sdk-java-configuration-plugins)。  |  不适用  |  不适用  |  TRUE  | 
|  collectSqlQueries  |  布尔值  |  True, False  |  尽量将 SQL 查询字符串记录在 SQL 子分段中。  |  不适用  |  不适用  |  FALSE  | 
|  contextPropagation  |  布尔值  |  True, False  |  如果是 true，则在线程之间自动传播 X-Ray 上下文。否则，需要使用 Thread Local 来存储上下文，并且需要手动跨线程传播。  |  不适用  |  不适用  |  TRUE  | 

### 日志记录配置


可以按照与 X-Ray SDK for Java 相同的方式配置 X-Ray 代理的日志级别。请参阅 [日志记录](xray-sdk-java-configuration.md#xray-sdk-java-configuration-logging)，详细了解如何使用 X-Ray SDK for Java 配置日志记录。

### 手动检测


如果希望在代理的自动检测之外再执行手动检测，请将 X-Ray SDK 作为依赖项添加到您的项目。请注意，[跟踪传入请求](xray-sdk-java-filters.md)中提及的 SDK 自定义 Servlet 筛选器与 X-Ray 代理不兼容。

**注意**  
您必须使用最新版本的 X-Ray SDK 来执行手动检测，同时还要使用代理。

如果您正在处理的是 Maven 项目，请将以下依赖项添加到您的 `pom.xml` 文件中。

```
<dependencies> 
  <dependency> 
    <groupId>com.amazonaws</groupId> 
    <artifactId>aws-xray-recorder-sdk-core</artifactId> 
    <version>2.11.0</version> 
  </dependency> 
  </dependencies>
```

如果您正在处理的是 Gradle 项目，请将以下依赖项添加到您的 `build.gradle` 文件中。

```
implementation 'com.amazonaws:aws-xray-recorder-sdk-core:2.11.0' 
```

在使用代理 IDs时，除了[注释、元数据和用户之外，](xray-sdk-java-segment.md)您还可以添加[自定义子细分](xray-sdk-java-subsegments.md)，就像使用普通 SDK 一样。代理会自动跨线程传播上下文，因此在使用多线程应用程序时，无需使用任何解决方法即可传播上下文。

## 问题排查


由于代理提供全自动检测功能，因此在遇到问题时可能很难确定问题的根本原因。如果 X-Ray 代理无法按预期运行，请查看以下问题和解决方案。X-Ray 代理和 SDK 使用 Jakarta Commons Logging（JCL）。若要查看日志记录输出，请确保将 JCL 桥接到您在类路径上的日志记录后端，如以下示例所示：`log4j-jcl` 或 `jcl-over-slf4j`。

### 问题：我的应用程序上已经启用了 Java 代理，但在 X-Ray 控制台上却什么都看不到。


 **X-Ray 进程守护程序是否在同一台计算机上运行？** 

如果不是，请参阅 [X-Ray 进程守护程序文档](https://docs.amazonaws.cn/xray/latest/devguide/xray-daemon.html)进行设置。

 **在应用程序日志中，是否看到类似于“正在初始化 X-Ray 代理记录器”这样的消息？** 

如果您已正确将代理添加到应用程序中，则在应用程序启动时，在开始接受请求之前，将在信息级别记录此消息。如果没有出现此消息，则说明您的 Java 进程未运行 Java 代理。确保您已正确执行所有设置步骤，不存在错别字。

 **在您的应用程序日志中，您是否看到几条错误消息，上面写着 “禁止 Amazon X-Ray 上下文缺失异常” 之类的内容？** 

之所以出现这些错误，是因为代理正在尝试检测下游请求，例如 Amazon SDK 请求或 SQL 查询，但代理无法自动创建区段。如果您看到其中许多错误消息，则代理可能并不是最适合您用例的工具，可能需要考虑改用 X-Ray SDK 进行手动检测。或者，可以启用 X-Ray SDK [调试日志](xray-sdk-java-configuration.md#xray-sdk-java-configuration-logging)，以查看上下文缺失异常发生位置的堆栈跟踪。可以用自定义分段封装代码的这些部分，这样可以解决这些错误。请参阅[检测启动代码](scorekeep-startup.md)中的示例代码，查看使用自定义分段包装下游请求的示例。

### 问题：我预期的一些分段没有出现在 X-Ray 控制台上


 **您的应用程序是否使用多线程？**

 如果您希望创建的某些分段未出现在控制台上，则可能是应用程序中的后台线程造成的。如果您的应用程序使用 “触发和忘记” 的后台线程执行任务，例如使用软件开发工具包一次性调用 Lambda 函数，或者定期轮询某些 HTTP 端点，则在代理跨线程传播上下文时，可能会使代理感到困惑。 Amazon 若要验证您遇到的是不是这个问题，可以启用 X-Ray SDK 调试日志并查看如下所示的消息：*未发射名为 <NAME> 的分段，因为它是正在进行中的子分段的父级*。若要解决此问题，可以尝试在服务器返回前加入后端线程以确保记录下在其中完成的全部工作。或者，也可以将代理的 `contextPropagation` 配置设置为 `false`，在后台禁用上下文传播。如果这样做，则必须使用自定义分段手动检测这些线程，或忽略它们造成的上下文缺失异常。

**您是否制定采样规则？** 

 如果 X-Ray 主机上出现了看似随机或意想不到的分段，或者您期望出现在控制台上的分段没有出现，那么可能遇到了采样问题。X-Ray 代理使用 X-Ray 控制台中的规则将集中采样应用于其创建的所有分段。默认规则为每秒 1 个分段，之后再加上 5% 的分段进行采样。这意味着可能不会对使用代理快速创建的区段进行采样。要解决这个问题，应该在 X-Ray 控制台上创建自定义采样规则，对所需的分段进行适当采样。有关更多信息，请参阅[采样](xray-console-sampling.md)。

# 配置 X-Ray SDK for Java
配置

**注意**  
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)。

X-Ray SDK for Java 包括提供全局记录器的、名为 `AWSXRay` 的类。这是可用于检测代码的 `TracingHandler`。您可以配置全局记录器以自定义为传入 HTTP 调用创建分段的 `AWSXRayServletFilter`。

**Topics**
+ [

## 服务插件
](#xray-sdk-java-configuration-plugins)
+ [

## 采样规则
](#xray-sdk-java-configuration-sampling)
+ [

## 日志记录
](#xray-sdk-java-configuration-logging)
+ [

## 分段侦听器
](#xray-sdk-java-configuration-listeners)
+ [

## 环境变量
](#xray-sdk-java-configuration-envvars)
+ [

## 系统属性
](#xray-sdk-java-configuration-sysprops)

## 服务插件


`plugins` 用于记录有关托管应用程序的服务的信息。

**插件**
+ Amazon EC2 — `EC2Plugin` 添加实例 ID、可用区和 CloudWatch 日志组。
+ Elastic Beanstalk - `ElasticBeanstalkPlugin` 添加环境名称、版本标签和部署 ID。
+ Amazon ECS — `ECSPlugin` 添加容器 ID。
+ Amazon EKS — `EKSPlugin` 添加容器 ID、集群名称、容器 ID 和 CloudWatch 日志组。

![\[使用 Amazon EC2 和 Elastic Beanstalk 插件对资源数据进行分段。\]](http://docs.amazonaws.cn/xray/latest/devguide/images/scorekeep-PUTrules-segment-resources.png)


要使用插件，请在 `AWSXRayRecorderBuilder` 上调用 `withPlugin`。

**Example src/main/java/scorekeep/WebConfig.java-录音机**  

```
import [com.amazonaws.xray.AWSXRay](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRay.html);
import [com.amazonaws.xray.AWSXRayRecorderBuilder](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRayRecorderBuilder.html);
import [com.amazonaws.xray.plugins.EC2Plugin](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/plugins/EC2Plugin.html);
import [com.amazonaws.xray.plugins.ElasticBeanstalkPlugin](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/plugins/ElasticBeanstalkPlugin.html);
import [com.amazonaws.xray.strategy.sampling.LocalizedSamplingStrategy](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/strategy/sampling/LocalizedSamplingStrategy.html);

@Configuration
public class WebConfig {
...
  static {
    AWSXRayRecorderBuilder builder = AWSXRayRecorderBuilder.standard().withPlugin(new EC2Plugin()).withPlugin(new ElasticBeanstalkPlugin());

    URL ruleFile = WebConfig.class.getResource("/sampling-rules.json");
    builder.withSamplingStrategy(new LocalizedSamplingStrategy(ruleFile));

    AWSXRay.setGlobalRecorder(builder.build());
  }
}
```

该 SDK 还使用插件设置为设置分段上的 `origin` 字段。这表示运行您的应用程序的 Amazon 资源类型。当您使用多个插件时，软件开发工具包使用以下解析顺序来确定来源： ElasticBeanstalk > EKS > ECS > EC2。

## 采样规则


该 SDK 使用您在 X-Ray 控制台中定义的采样规则来确定要记录的请求。默认规则跟踪每秒的第一个请求，以及所有将跟踪发送到 X-Ray 的服务的任何其他请求的百分之五。[在 X-Ray 控制台中创建其他规则](xray-console-sampling.md)以自定义为每个应用程序记录的数据量。

该 SDK 按照定义的顺序应用自定义规则。如果请求与多个自定义规则匹配，则 SDK 仅应用第一条规则。

**注意**  
如果 SDK 无法访问 X-Ray 来获取采样规则，它将恢复为默认的本地规则，即每秒第一个请求以及每个主机所有其他请求的百分之五。如果主机无权调用采样，或者无法连接到 X-Ray 守护程序 APIs，后者充当 SDK 发出的 API 调用的 TCP 代理，则可能会发生这种情况。

您还可以将 SDK 配置为从 JSON 文档加载采样规则。在 X-Ray 采样不可用的情况下，SDK 可以使用本地规则作为备份，也可以只使用本地规则。

**Example sampling-rules.json**  

```
{
  "version": 2,
  "rules": [
    {
      "description": "Player moves.",
      "host": "*",
      "http_method": "*",
      "url_path": "/api/move/*",
      "fixed_target": 0,
      "rate": 0.05
    }
  ],
  "default": {
    "fixed_target": 1,
    "rate": 0.1
  }
}
```

此示例定义了一个自定义规则和一个默认规则。自定义规则采用百分之五的采样率，对于 `/api/move/` 之下的路径要跟踪的请求数量不设下限。默认规则中每秒的第一个请求以及其他请求的百分之十。

在本地定义规则的缺点是，固定目标由记录器的每个实例独立应用而不是由 X-Ray 服务管理。随着您部署更多主机，固定速率会成倍增加，这使得控制记录的数据量变得更加困难。

开启后 Amazon Lambda，您无法修改采样率。如果您的函数由检测服务调用，Lambda 将记录生成由该服务采样的请求的调用。如果启用了活动跟踪且不存在任何跟踪标头，则 Lambda 会做出采样决定。

要在 Spring 中提供备份规则，请使用配置类中的 `CentralizedSamplingStrategy` 配置全局记录器。

**Example src/main/java/myapp/WebConfig.java-录制器配置**  

```
import [com.amazonaws.xray.AWSXRay](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRay.html);
import [com.amazonaws.xray.AWSXRayRecorderBuilder](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRayRecorderBuilder.html);
import [com.amazonaws.xray.javax.servlet.AWSXRayServletFilter](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/javax/servlet/AWSXRayServletFilter.html);
import [com.amazonaws.xray.plugins.EC2Plugin](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/plugins/EC2Plugin.html);
import [com.amazonaws.xray.strategy.sampling.LocalizedSamplingStrategy](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/strategy/sampling/LocalizedSamplingStrategy.html);

@Configuration
public class WebConfig {

  static {
  AWSXRayRecorderBuilder builder = AWSXRayRecorderBuilder.standard().withPlugin(new EC2Plugin());

  URL ruleFile = WebConfig.class.getResource("/sampling-rules.json");
  builder.withSamplingStrategy(new CentralizedSamplingStrategy(ruleFile));

  AWSXRay.setGlobalRecorder(builder.build());
}
```

对于 Tomcat，添加一个扩展 `ServletContextListener` 的侦听器，并在部署描述符中注册该侦听器。

**Example src/com/myapp/web/Startup.java**  

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

import java.net.URL;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class Startup implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent event) {
        AWSXRayRecorderBuilder builder = AWSXRayRecorderBuilder.standard().withPlugin(new EC2Plugin());

        URL ruleFile = Startup.class.getResource("/sampling-rules.json");
        builder.withSamplingStrategy(new CentralizedSamplingStrategy(ruleFile));

        AWSXRay.setGlobalRecorder(builder.build());
    }

    @Override
    public void contextDestroyed(ServletContextEvent event) { }
}
```

**Example WEB-INF/web.xml**  

```
...
  <listener>
    <listener-class>com.myapp.web.Startup</listener-class>
  </listener>
```

若要仅使用本地规则，请将 `CentralizedSamplingStrategy` 替换为 `LocalizedSamplingStrategy`。

```
builder.withSamplingStrategy(new LocalizedSamplingStrategy(ruleFile));
```

## 日志记录


默认情况下，SDK 会将 `ERROR` 级消息输出到应用程序日志。可以在 SDK 上启用调试级别日志记录，将更详细的日志输出到应用程序日志文件。有效的日志级别为 `DEBUG`、`INFO`、`WARN`、`ERROR` 和 `FATAL`。`FATAL` 日志级别会静默所有日志消息，因为 SDK 不会在严重级别记录日志。

**Example application.properties**  
使用 `logging.level.com.amazonaws.xray` 属性设置日志记录级别。  

```
logging.level.com.amazonaws.xray = DEBUG
```

当您手动[生成子分段](xray-sdk-java-subsegments.md)时，使用调试日志来识别诸如未结束子分段之类的问题。

### 跟踪 ID 注入到日志


要将当前完全限定的跟踪 ID 公开到日志语句，您可以将此 ID 注入到映射的诊断上下文 (MDC)。在分段生命周期事件过程中使用 `SegmentListener` 接口从 X-Ray 记录器调用方法。当分段或子分段开始时，使用密钥 `AWS-XRAY-TRACE-ID` 将限定的跟踪 ID 注入到 MDC 中。当该分段结束后，从 MDC 中删除密钥。这会向正在使用的日志库公开跟踪 ID。当子分段结束时，其父级 ID 将注入到 MDC 中。

**Example 完全限定的跟踪 ID**  
完全限定的 ID 表示为 `TraceID@EntityID`  

```
1-5df42873-011e96598b447dfca814c156@541b3365be3dafc3
```

此功能适用于使用适用于 Java 的 Amazon X-Ray SDK 进行检测的 Java 应用程序，并支持以下日志配置：
+ SLF4带有 Logback 后端的 J 前端 API
+ SLF4带有 Log4J2 后端的 J 前端 API
+ 带有 Log4J2 后端的 Log4J2 前端 API

请查看以下选项卡，了解每个前端和每个后端的需求。

------
#### [ SLF4J Frontend ]

1. 将以下 Maven 依赖项添加到您的项目中。

   ```
   <dependency>
       <groupId>com.amazonaws</groupId>
       <artifactId>aws-xray-recorder-sdk-slf4j</artifactId>
       <version>2.11.0</version>
   </dependency>
   ```

1. 构建 `AWSXRayRecorder` 时包含 `withSegmentListener` 方法。这会添加一个`SegmentListener`类，该类会自动向 SLF4 J MDC 注 IDs 入新的轨迹。

   `SegmentListener` 采用可选字符串作为参数来配置日志语句前缀。可以通过以下方式配置前缀：
   + **无** - 使用默认 `AWS-XRAY-TRACE-ID` 前缀。
   + **空** 使用空字符串（例如 `""`）。
   + **自定义** - 使用在字符串中定义的自定义前缀。  
**Example `AWSXRayRecorderBuilder` statement**  

   ```
   AWSXRayRecorderBuilder builder = AWSXRayRecorderBuilder
           .standard().withSegmentListener(new SLF4JSegmentListener("CUSTOM-PREFIX"));
   ```

------
#### [ Log4J2 front end ]

1. 将以下 Maven 依赖项添加到您的项目中。

   ```
   <dependency>
       <groupId>com.amazonaws</groupId>
       <artifactId>aws-xray-recorder-sdk-log4j</artifactId>
       <version>2.11.0</version>
   </dependency>
   ```

1. 构建 `AWSXRayRecorder` 时包含 `withSegmentListener` 方法。这将添加一个`SegmentListener`类，该类会自动向 SLF4 J MDC 注 IDs 入新的完全限定轨迹。

   `SegmentListener` 采用可选字符串作为参数来配置日志语句前缀。可以通过以下方式配置前缀：
   + **无** - 使用默认 `AWS-XRAY-TRACE-ID` 前缀。
   + **空** - 使用空字符串（例如 `""`）并删除前缀。
   + **自定义** - 使用在字符串中定义的自定义前缀。  
**Example `AWSXRayRecorderBuilder` statement**  

   ```
   AWSXRayRecorderBuilder builder = AWSXRayRecorderBuilder
           .standard().withSegmentListener(new Log4JSegmentListener("CUSTOM-PREFIX"));
   ```

------
#### [ Logback backend ]

要将跟踪 ID 插入到日志事件中，您必须修改记录器的 `PatternLayout`，它设置每个日志记录语句的格式。

1. 查找在哪里配置的 `patternLayout`。您可以通过编程方式或通过 XML 配置文件执行此操作。要了解更多信息，请参阅 [Logback 配置](http://logback.qos.ch/manual/configuration.html)。

1. 在 `patternLayout` 中的任意位置插入 `%X{}`，将跟踪 ID 插入到未来的日志记录语句中。`%X{AWS-XRAY-TRACE-ID}` 指示您正在检索的值包含由 MDC 提供的密钥。要 PatternLayouts 在 Logback 中了解更多信息，请参阅[PatternLayout](https://logback.qos.ch/manual/layouts.html#ClassicPatternLayout)。

------
#### [ Log4J2 backend ]

1. 查找在哪里配置的 `patternLayout`。您可以通过编程方式执行此操作，也可以通过以 XML、JSON、YAML 或属性格式编写的配置文件来执行此操作。

   如需详细了解如何通过配置文件配置 Log4J2，请参阅[配置](https://logging.apache.org/log4j/2.x/manual/configuration.html)。

   如需详细了解如何以编程方式配置 Log4J2，请参阅[编程式配置](https://logging.apache.org/log4j/2.x/manual/customconfig.html)。

1. 在 `PatternLayout` 中的任意位置插入 `%X{}`，将跟踪 ID 插入到未来的日志记录语句中。`%X{AWS-XRAY-TRACE-ID}` 指示您正在检索的值包含由 MDC 提供的密钥。[要了解有关 Log4J2 PatternLayouts 的更多信息，请参阅模式布局。](https://logging.apache.org/log4j/2.x/manual/layouts.html#Pattern_Layout)

------

**跟踪 ID 注入示例**  
以下显示了一个经过修改包含跟踪 ID 的 `PatternLayout` 字符串。跟踪 ID 在线程名称 (`%t`) 之后和日志级别 (`%-5p`) 之前输出。

**Example `PatternLayout`（带 ID 注入）**  

```
%d{HH:mm:ss.SSS} [%t] %X{AWS-XRAY-TRACE-ID} %-5p %m%n
```

Amazon X-Ray 自动在日志语句中打印密钥和跟踪 ID，便于解析。下面显示了使用已修改的 `PatternLayout` 的日志语句。

**Example 带 ID 注入的日志语句**  

```
2019-09-10 18:58:30.844 [nio-5000-exec-4]  AWS-XRAY-TRACE-ID: 1-5d77f256-19f12e4eaa02e3f76c78f46a@1ce7df03252d99e1 WARN 1 - Your logging message here
```

 日志记录消息本身保存在模式 `%m` 中，并在调用记录器时设置。

## 分段侦听器


分段侦听器是一个用于拦截生命周期事件（例如，由 `AWSXRayRecorder` 生成的分段的开始和结束）的接口。分段侦听器事件函数的实现方式可能包括：在使用 [https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/listeners/SegmentListener.html#onBeginSubsegment-com.amazonaws.xray.entities.Subsegment-](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/listeners/SegmentListener.html#onBeginSubsegment-com.amazonaws.xray.entities.Subsegment-) 创建所有子分段时，为它们添加相同的注释；使用 [https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/listeners/SegmentListener.html#afterEndSegment-com.amazonaws.xray.entities.Segment-](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/listeners/SegmentListener.html#afterEndSegment-com.amazonaws.xray.entities.Segment-) 在将每个分段发送到进程守护程序后记录一条消息；或者使用 [https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/listeners/SegmentListener.html#beforeEndSubsegment-com.amazonaws.xray.entities.Subsegment-](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/listeners/SegmentListener.html#beforeEndSubsegment-com.amazonaws.xray.entities.Subsegment-) 记录由 SQL 拦截程序发送的查询，以验证子分段是否代表 SQL 查询，如果是，则添加其他元数据。

要查看 `SegmentListener` 函数的完整列表，请访问 [Amazon X-Ray Recorder SDK for Java API](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/listeners/SegmentListener.html) 相关文档。

以下示例说明如何在使用 [https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/listeners/SegmentListener.html#onBeginSubsegment-com.amazonaws.xray.entities.Subsegment-](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/listeners/SegmentListener.html#onBeginSubsegment-com.amazonaws.xray.entities.Subsegment-) 创建所有子分段时向所有子分段添加一致的注释，以及如何使用 [https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/listeners/SegmentListener.html#afterEndSegment-com.amazonaws.xray.entities.Segment-](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/listeners/SegmentListener.html#afterEndSegment-com.amazonaws.xray.entities.Segment-) 在每个分段末尾打印日志消息。

**Example MySegmentListener.java**  

```
import com.amazonaws.xray.entities.Segment;
import com.amazonaws.xray.entities.Subsegment;
import com.amazonaws.xray.listeners.SegmentListener;

public class MySegmentListener implements SegmentListener {
    .....
    
    @Override
    public void onBeginSubsegment(Subsegment subsegment) {
        subsegment.putAnnotation("annotationKey", "annotationValue");
    }
    
    @Override
    public void afterEndSegment(Segment segment) {
        // Be mindful not to mutate the segment
        logger.info("Segment with ID " + segment.getId());
    }
}
```

然后，在构建 `AWSXRayRecorder` 时引用此自定义分段侦听器。

**Example AWSXRayRecorderBuilder 声明**  

```
AWSXRayRecorderBuilder builder = AWSXRayRecorderBuilder
        .standard().withSegmentListener(new MySegmentListener());
```

## 环境变量


您可以使用环境变量来配置 X-Ray SDK for Java。SDK 支持以下变量。
+ `AWS_XRAY_CONTEXT_MISSING` - 设置为 `RUNTIME_ERROR` 在您的已检测代码尝试在分段未打开的情况下记录数据时引发异常。

**有效值**
  + `RUNTIME_ERROR`— 引发运行时异常。
  + `LOG_ERROR`— 记录错误并继续（默认）。
  + `IGNORE_ERROR`— 忽略错误并继续。

  对于在未打开任何请求时运行的启动代码或者会生成新线程的代码，如果您尝试在其中使用检测过的客户端，则可能发生与缺失分段或子分段相关的错误。
+ `AWS_XRAY_DAEMON_ADDRESS` - 设置 X-Ray 进程守护程序侦听器的主机和端口。默认情况下，SDK 使用用于跟踪数据（UDP）和采样（TCP）的 `127.0.0.1:2000`。如果您已将进程守护程序配置为[侦听不同端口](xray-daemon-configuration.md)或者进程守护程序在另一台主机上运行，则使用此变量。

**Format**
  + **同一个端口** — `address:port`
  + **不同的端口** — `tcp:address:port udp:address:port`
+ `AWS_LOG_GROUP` - 将日志组的名称设置为与您的应用程序关联的日志组。如果您的日志组使用与您的应用程序相同的 Amazon 账户和区域，X-Ray 将使用此指定的日志组自动搜索应用程序的区段数据。有关日志组的更多信息，请参阅[使用日志组和日志流](https://docs.amazonaws.cn/AmazonCloudWatch/latest/logs/Working-with-log-groups-and-streams.html)。
+ `AWS_XRAY_TRACING_NAME` - 设置 SDK 用于进行分段的服务名称。覆盖您根据 servlet 筛选器的[分段命名策略](xray-sdk-java-filters.md#xray-sdk-java-filters-naming)设置的服务名称。

环境变量覆盖在代码中设置的等效[系统属性](#xray-sdk-java-configuration-sysprops)和值。

## 系统属性


您可以将系统属性用作[环境变量](#xray-sdk-java-configuration-envvars)的 JVM 特定替代项。SDK 支持以下属性：
+ `com.amazonaws.xray.strategy.tracingName` - 等效于 `AWS_XRAY_TRACING_NAME`。
+ `com.amazonaws.xray.emitters.daemonAddress` - 等效于 `AWS_XRAY_DAEMON_ADDRESS`。
+ `com.amazonaws.xray.strategy.contextMissingStrategy` - 等效于 `AWS_XRAY_CONTEXT_MISSING`。

如果同时设置系统属性和等效的环境变量，则使用环境变量值。每种方法都会覆盖在代码中设置的值。

# 使用适用于 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)。

您可以使用 X-Ray SDK 来跟踪您的应用程序在 Amazon EC2 或 Amazon ECS 的 EC2 实例上提供的 Amazon Elastic Beanstalk传入 HTTP 请求。

使用 `Filter` 检测传入 HTTP 请求。在您添加 X-Ray servlet 筛选器到应用程序时，适用于 Java 的 X-Ray 开发工具包为每个采样请求创建分段。此分段包括 HTTP 请求的计时、方法和处置。其他检测会在此分段上创建子分段。

**注意**  
对于 Amazon Lambda 函数，Lambda 会为每个采样请求创建一个分段。请参阅[Amazon Lambda 和 Amazon X-Ray](xray-services-lambda.md)了解更多信息。

每个分段都有一个名称，用于在服务映射中标识您的应用程序。可以静态命名分段，也可以将 SDK 配置为根据传入请求中的主机标头对其进行动态命名。动态命名允许根据请求中的域名对跟踪进行分组，并且在名称不匹配预期模式时（例如，如果主机标头是伪造的）应用默认名称。

**转发的请求**  
如果负载均衡器或其他中间将请求转发到您的应用程序，X-Ray 会提取请求 `X-Forwarded-For` 标头中的客户端 IP 而非 IP 数据包中的源 IP。由于转发的请求记录的客户端 IP 可以伪造，因此不应信任。

在转发请求时，SDK 在分段中设置附加字段来指示此行为。如果分段包含设置为 `x_forwarded_for` 的字段 `true`，则从 HTTP 请求的 `X-Forwarded-For` 标头获取客户端 IP。

信息处理程序使用包含以下信息的 `http` 数据块为每个传入请求创建一个分段：
+ **HTTP 方法** - GET、POST、PUT、DELETE 等。
+ **客户端地址** - 发送请求的客户端的 IP 地址。
+ **响应代码** - 已完成请求的 HTTP 响应代码。
+ **时间** - 开始时间（收到请求时）和结束时间（发送响应时）。
+ **用户代理** - 请求中的 `user-agent`。
+ **内容长度** - 响应中的 `content-length`。

**Topics**
+ [

## 向应用程序中添加跟踪筛选器 (Tomcat)
](#xray-sdk-java-filters-tomcat)
+ [

## 为您的应用程序添加跟踪筛选器 (Spring)
](#xray-sdk-java-filters-spring)
+ [

## 配置分段命名策略
](#xray-sdk-java-filters-naming)

## 向应用程序中添加跟踪筛选器 (Tomcat)


对于 Tomcat，请将 `<filter>` 添加到您项目的 `web.xml` 文件。使用 `fixedName` 参数可指定要应用于为传入请求创建的分段的[服务名称](#xray-sdk-java-filters-naming)。

**Example WEB-INF/web.xml - Tomcat**  

```
<filter>
  <filter-name>AWSXRayServletFilter</filter-name>
  <filter-class>com.amazonaws.xray.javax.servlet.AWSXRayServletFilter</filter-class>
  <init-param>
    <param-name>fixedName</param-name>
    <param-value>MyApp</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>AWSXRayServletFilter</filter-name>
  <url-pattern>*</url-pattern>
</filter-mapping>
```

## 为您的应用程序添加跟踪筛选器 (Spring)


对于 Spring，请将 `Filter` 添加到您的 `WebConfig` 类。将分段名称作为字符串传递到 [https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/javax/servlet/AWSXRayServletFilter.html](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/javax/servlet/AWSXRayServletFilter.html) 构造函数。

**Example src/main/java/myapp/WebConfig.java-春季**  

```
package myapp;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Bean;
import javax.servlet.Filter;
import [com.amazonaws.xray.javax.servlet.AWSXRayServletFilter](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/javax/servlet/AWSXRayServletFilter.html);

@Configuration
public class WebConfig {

  @Bean
  public Filter TracingFilter() {
    return new AWSXRayServletFilter("Scorekeep");
  }
}
```

## 配置分段命名策略


Amazon X-Ray 使用*服务名称*来标识您的应用程序，并将其与您的应用程序使用的其他应用程序、数据库 APIs、外部数据库和 Amazon 资源区分开来。当 X-Ray SDK 为传入请求生成分段时，会将应用程序的服务名称记录在分段的[名称字段](xray-api-segmentdocuments.md#api-segmentdocuments-fields)中。

X-Ray SDK 可以用在 HTTP 请求标头中的 hostname 来命名分段。不过，此标头可以伪造，会导致服务地图中出现意料之外的节点。为防止 SDK 由于包含伪造的主机标头的请求而错误地命名分段，必须为传入请求指定一个默认名称。

如果应用程序为多个域的请求提供服务，则可以将 SDK 配置为使用动态命名策略以在分段名称中反映出这一点。动态命名策略允许 SDK 将主机名用于符合预期模式的请求，并将默认名称应用于不符合预期模式的请求。

例如，可能有一款应用程序为发送到三个子域的请求提供服务，分别为 `www.example.com`、`api.example.com` 和 `static.example.com`。可以使用格式 `*.example.com` 的动态命名策略以识别包含不同名称的子域的分段，服务地图上因此会显示三个服务节点。如果应用程序收到包含与该格式不匹配的 hostname 的请求，您将会在服务地图上看到第四个节点，以及您指定的回退名称。

要对所有请求分段使用同一名称，可在初始化 servlet 筛选器时指定应用程序名称，如[上一部分](#xray-sdk-java-filters-tomcat)中所示。这与[SegmentNamingStrategy](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/strategy/SegmentNamingStrategy.html)通过调用`SegmentNamingStrategy.fixed()`并传递给[https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/javax/servlet/AWSXRayServletFilter.html](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/javax/servlet/AWSXRayServletFilter.html)构造函数来创建固定值具有相同的效果。

**注意**  
您可以使用 `AWS_XRAY_TRACING_NAME` [环境变量](xray-sdk-java-configuration.md#xray-sdk-java-configuration-envvars)覆盖您在代码中定义的默认服务名称。

动态命名策略定义一个主机名应匹配的模式和一个在 HTTP 请求中的主机名与该模式不匹配时要使用的默认名称。要在 Tomcat 中动态命名分段，可使用 `dynamicNamingRecognizedHosts` 和 `dynamicNamingFallbackName` 相应地定义模式和默认名称。

**Example WEB-INF/web.xml - 带动态命名的 Servlet 筛选器**  

```
<filter>
  <filter-name>AWSXRayServletFilter</filter-name>
  <filter-class>com.amazonaws.xray.javax.servlet.AWSXRayServletFilter</filter-class>
  <init-param>
    <param-name>dynamicNamingRecognizedHosts</param-name>
    <param-value>*.example.com</param-value>
  </init-param>
  <init-param>
    <param-name>dynamicNamingFallbackName</param-name>
    <param-value>MyApp</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>AWSXRayServletFilter</filter-name>
  <url-pattern>*</url-pattern>
</filter-mapping>
```

对于 Spring，[SegmentNamingStrategy](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/strategy/SegmentNamingStrategy.html)通过调用创建一个动态`SegmentNamingStrategy.dynamic()`，然后将其传递给`AWSXRayServletFilter`构造函数。

**Example src/main/java/myapp/WebConfig.java-带动态命名的 servlet 过滤器**  

```
package myapp;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Bean;
import javax.servlet.Filter;
import [com.amazonaws.xray.javax.servlet.AWSXRayServletFilter](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/javax/servlet/AWSXRayServletFilter.html);
import [com.amazonaws.xray.strategy.SegmentNamingStrategy](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/strategy/SegmentNamingStrategy.html);

@Configuration
public class WebConfig {

  @Bean
  public Filter TracingFilter() {
    return new AWSXRayServletFilter(SegmentNamingStrategy.dynamic("MyApp", "*.example.com"));
  }
}
```

# 使用适用于 Java 的 X-Ray SD Amazon K 追踪 SDK 调用
Amazon SDK 客户端

**注意**  
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)。

当您的应用调用 Amazon Web Services 服务 以存储数据、写入队列或发送通知时，适用于 Java 的 X-Ray SDK 会按[子分段](xray-sdk-java-subsegments.md)跟踪下游的调用。所跟踪的 Amazon Web Services 服务 以及您在这些服务中访问的资源（例如，Amazon S3 存储桶或 Amazon SQS 队列），在 X-Ray 控制台的跟踪地图上显示为下游节点。

当您在生成中包括 `aws-sdk` 和 `aws-sdk-instrumentor` [子模块](xray-sdk-java.md#xray-sdk-java-submodules)时，X-Ray SDK for Java 自动检测所有 Amazon SDK 客户端。如果您未包括 Instrumentor 子模块，则可以选择检测一些客户端，同时排除另一些。

要检测单个客户端，请从版本中移除`aws-sdk-instrumentor`子模块，然后使用该服务的客户端生成器在 Amazon SDK 客户端`TracingHandler`上添加一个`XRayClient`。

例如，要检测 `AmazonDynamoDB` 客户端，请将跟踪处理程序传递到 `AmazonDynamoDBClientBuilder`。

**Example MyModel.java-DynamoDB 客户端**  

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

...
public class MyModel {
  private AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard()
        .withRegion(Regions.fromName(System.getenv("AWS_REGION")))
        .withRequestHandlers(new TracingHandler(AWSXRay.getGlobalRecorder()))
        .build();
...
```

对于所有服务，都可以在 X-Ray 控制台中看到调用的 API 的名称。X-Ray 开发工具包会为一部分服务将信息添加到分段，从而在服务地图中提供更高的粒度。

例如，当使用经过检测的 DynamoDB 客户端发出调用时，对于针对表的调用，开发工具包会将表名称添加到分段中。在控制台中，每个表在服务地图中显示为一个独立的节点，以及没有表作为目标的调用的一般 DynamoDB 节点。

**Example 对 DynamoDB 进行调用以保存项目的子分段**  

```
{
  "id": "24756640c0d0978a",
  "start_time": 1.480305974194E9,
  "end_time": 1.4803059742E9,
  "name": "DynamoDB",
  "namespace": "aws",
  "http": {
    "response": {
      "content_length": 60,
      "status": 200
    }
  },
  "aws": {
    "table_name": "scorekeep-user",
    "operation": "UpdateItem",
    "request_id": "UBQNSO5AEM8T4FDA4RQDEB94OVTDRVV4K4HIRGVJF66Q9ASUAAJG",
  }
}
```

在您访问指定的资源时，对以下服务的调用会在服务地图中创建额外的节点。没有定向到特定资源的调用，为服务创建了通用节点。
+ **Amazon DynamoDB** - 表名称
+ **Amazon Simple Storage Service** - 存储桶和键名称
+ **Amazon Simple Queue Service** - 队列名称

要 Amazon Web Services 服务 使用 适用于 Java 的 Amazon SDK 2.2 及更高版本检测下游调用，可以在编译配置中省略该`aws-xray-recorder-sdk-aws-sdk-v2-instrumentor`模块。改为包含 `aws-xray-recorder-sdk-aws-sdk-v2 module`，然后通过为它们配置 `TracingInterceptor` 来检测各个客户端。

**Example 适用于 Java 的 Amazon SDK 2.2 及更高版本-追踪拦截器**  

```
import com.amazonaws.xray.interceptors.TracingInterceptor;
import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
//...
public class MyModel {
private DynamoDbClient client = DynamoDbClient.builder()
.region(Region.US_WEST_2)
.overrideConfiguration(ClientOverrideConfiguration.builder()
.addExecutionInterceptor(new TracingInterceptor())
.build()
)
.build();
//...
```

# 使用适用于 Java 的 X-Ray 开发工具包跟踪对下游 HTTP Web 服务的调用
传出 HTTP 调用

**注意**  
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)。

当您的应用程序调用微服务或公共 HTTP 时 APIs，您可以使用适用于 Java 的 X-Ray SDK 版本`HttpClient`来检测这些调用，并将该 API 作为下游服务添加到服务图中。

适用于 Java 的 X-Ray SDK 包括`DefaultHttpClient`一些`HttpClientBuilder`类，这些类可以用来代替 Apache HttpComponents 等效项来检测传出的 HTTP 调用。
+ `com.amazonaws.xray.proxies.apache.http.DefaultHttpClient` - `org.apache.http.impl.client.DefaultHttpClient`
+ `com.amazonaws.xray.proxies.apache.http.HttpClientBuilder` - `org.apache.http.impl.client.HttpClientBuilder`

这些库位于 [`aws-xray-recorder-sdk-apache-http`](xray-sdk-java.md) 子模块中。

您可以使用 X-Ray 等效项替换现有的导入语句来检测所有客户端，或者在您初始化客户端以检测特定客户端时使用完全限定名称。

**Example HttpClientBuilder**  

```
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import [com.amazonaws.xray.proxies.apache.http.HttpClientBuilder](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/proxies/apache/http/HttpClientBuilder.html);
...
  public String randomName() throws IOException {
    CloseableHttpClient httpclient = HttpClientBuilder.create().build();
    HttpGet httpGet = new HttpGet("http://names.example.com/api/");
    CloseableHttpResponse response = httpclient.execute(httpGet);
    try {
      HttpEntity entity = response.getEntity();
      InputStream inputStream = entity.getContent();
      ObjectMapper mapper = new ObjectMapper();
      Map<String, String> jsonMap = mapper.readValue(inputStream, Map.class);
      String name = jsonMap.get("name");
      EntityUtils.consume(entity);
      return name;
    } finally {
      response.close();
    }
  }
```

在您检测对下游 Web API 的调用时，适用于 Java 的 X-Ray 开发工具包会使用有关 HTTP 请求和响应的信息记录子分段。X-Ray 使用子分段为远程 API 生成推断分段。

**Example 下游 HTTP 调用的子分段**  

```
{
  "id": "004f72be19cddc2a",
  "start_time": 1484786387.131,
  "end_time": 1484786387.501,
  "name": "names.example.com",
  "namespace": "remote",
  "http": {
    "request": {
      "method": "GET",
      "url": "https://names.example.com/"
    },
    "response": {
      "content_length": -1,
      "status": 200
    }
  }
}
```

**Example 下游 HTTP 调用的推断分段**  

```
{
  "id": "168416dc2ea97781",
  "name": "names.example.com",
  "trace_id": "1-62be1272-1b71c4274f39f122afa64eab",
  "start_time": 1484786387.131,
  "end_time": 1484786387.501,
  "parent_id": "004f72be19cddc2a",
  "http": {
    "request": {
      "method": "GET",
      "url": "https://names.example.com/"
    },
    "response": {
      "content_length": -1,
      "status": 200
    }
  },
  "inferred": true
}
```

# 使用适用于 Java 的 X-Ray 开发工具包跟踪 SQL 查询
SQL 查询

**注意**  
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)。

## SQL 拦截器


通过将适用于 Java 的 X-Ray 开发工具包 JDBC 拦截程序添加到数据源配置来检测 SQL 数据库查询。
+  **PostgreSQL** – `com.amazonaws.xray.sql.postgres.TracingInterceptor` 
+  **MySQL** – `com.amazonaws.xray.sql.mysql.TracingInterceptor` 

这些拦截程序分别位于 [`aws-xray-recorder-sql-postgres` 和 `aws-xray-recorder-sql-mysql` 子模块](xray-sdk-java.md)中。它们实现 `org.apache.tomcat.jdbc.pool.JdbcInterceptor` 并与 Tomcat 连接池兼容。

**注意**  
为了安全起见，SQL 拦截程序不在子分段中记录 SQL 查询本身。

对于 Spring，在属性文件中添加拦截程序并使用 Spring Boot 的 `DataSourceBuilder` 构建数据源。

**Example `src/main/java/resources/application.properties` - ostgreSQL JDBC 拦截器**  

```
spring.datasource.continue-on-error=true
spring.jpa.show-sql=false
spring.jpa.hibernate.ddl-auto=create-drop
spring.datasource.jdbc-interceptors=com.amazonaws.xray.sql.postgres.TracingInterceptor
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL94Dialect
```

**Example `src/main/java/myapp/WebConfig.java` - 数据源**  

```
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

import javax.servlet.Filter;
import javax.sql.DataSource;
import java.net.URL;

@Configuration
@EnableAutoConfiguration
@EnableJpaRepositories("myapp")
public class RdsWebConfig {

  @Bean
  @ConfigurationProperties(prefix = "spring.datasource")
  public DataSource dataSource() {
      logger.info("Initializing PostgreSQL datasource");
      return DataSourceBuilder.create()
              .driverClassName("org.postgresql.Driver")
              .url("jdbc:postgresql://" + System.getenv("RDS_HOSTNAME") + ":" + System.getenv("RDS_PORT") + "/ebdb")
              .username(System.getenv("RDS_USERNAME"))
              .password(System.getenv("RDS_PASSWORD"))
              .build();
  }
...
}
```

对于 Tomcat，使用对适用于 Java 类的 X-Ray 开发工具包的引用来对 JDBC 数据源调用 `setJdbcInterceptors`。

**Example `src/main/myapp/model.java` - 数据源**  

```
import org.apache.tomcat.jdbc.pool.DataSource;
...
DataSource source = new DataSource();
source.setUrl(url);
source.setUsername(user);
source.setPassword(password);
source.setDriverClassName("com.mysql.jdbc.Driver");
source.setJdbcInterceptors("com.amazonaws.xray.sql.mysql.TracingInterceptor;");
```

Tomcat JDBC 数据源库包含在适用于 Java 的 X-Ray 开发工具包中，但您可以将其声明为提供的依赖关系来记载您将会使用它。

**Example `pom.xml` - JDBC 数据源**  

```
<dependency>
  <groupId>org.apache.tomcat</groupId>
  <artifactId>tomcat-jdbc</artifactId>
  <version>8.0.36</version>
  <scope>provided</scope>
</dependency>
```

## 原生 SQL 跟踪装饰器

+ 将 [https://github.com/aws/aws-xray-sdk-java/tree/master/aws-xray-recorder-sdk-sql](https://github.com/aws/aws-xray-sdk-java/tree/master/aws-xray-recorder-sdk-sql) 添加到依赖项。
+ 装饰您的数据库数据源、连接或语句。

  ```
  dataSource = TracingDataSource.decorate(dataSource)
  connection = TracingConnection.decorate(connection)
  statement = TracingStatement.decorateStatement(statement)
  preparedStatement = TracingStatement.decoratePreparedStatement(preparedStatement, sql)
  callableStatement = TracingStatement.decorateCallableStatement(callableStatement, sql)
  ```

# 使用适用于 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();
}
```

# 使用 X-Ray SDK for Java，将注释和元数据添加到分段
注释和元数据

**注意**  
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)。

可以利用注释和元数据记录与请求、环境或应用程序相关的其他信息。可以将注释和元数据添加到 X-Ray 开发工具包创建的分段或您创建的自定义子分段。

**注释**是带字符串、数字或布尔值的键值对。系统会对注释编制索引，以便与[筛选表达式](xray-console-filters.md)一起使用。使用注释记录要用于对控制台中的跟踪进行分组的数据或在调用 [https://docs.amazonaws.cn/xray/latest/api/API_GetTraceSummaries.html](https://docs.amazonaws.cn/xray/latest/api/API_GetTraceSummaries.html) API 时使用的数据。

**元数据**是可以具有任何类型值的键-值对，包括对象和列表，但没有编制索引，无法与筛选条件表达式一起使用。使用元数据记录要存储在跟踪中但不需要用于搜索跟踪的其他数据。

除了注释和元数据之外，您还可以在分段上[记录用户 ID 字符串](#xray-sdk-java-segment-userid)。用户 IDs 被记录在区段的单独字段中，并编制索引以供搜索使用。

**Topics**
+ [

## 使用 X-Ray SDK for Java 记录注释
](#xray-sdk-java-segment-annotations)
+ [

## 使用 X-Ray SDK for Java 记录元数据
](#xray-sdk-java-segment-metadata)
+ [

## 使用适用于 Java IDs 的 X-Ray SDK 录制用户
](#xray-sdk-java-segment-userid)

## 使用 X-Ray SDK for Java 记录注释


使用注释记录有关要为其编制索引以进行搜索的分段和子分段的信息。

**注释要求**
+ **键** - X-Ray 注释的键最多可以包含 500 个字母数字字符。除了点或句点（.）之外，不能使用空格或符号
+ **值** - X-Ray 注释的值最多可以包含 1,000 个 Unicode 字符。
+ **注释**的数量 - 每个跟踪最多可使用 50 条注释。

**记录注释**

1. 从 `AWSXRay` 获取对当前分段或子分段的引用。

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

   或者

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

1. 调用带有字符串键和布尔值、数字值或字符串值的 `putAnnotation`。

   ```
   document.putAnnotation("mykey", "my value");
   ```

   以下示例说明如何使用包含点和布尔值、数字值或字符串值的字符串键调用 `putAnnotation`。

   ```
   document.putAnnotation("testkey.test", "my value");
   ```

开发工具包将注释以键-值对的形式记录在分段文档的 `annotations` 对象中。使用相同键调用两次 `putAnnotation` 将覆盖同一分段或子分段上之前记录的值。

要查找具有带特定值的注释的跟踪，请在`annotation[key]`筛选表达式[中使用 ](xray-console-filters.md) 关键字。

**Example [https://github.com/awslabs/eb-java-scorekeep/tree/xray/src/main/java/scorekeep/GameModel.java](https://github.com/awslabs/eb-java-scorekeep/tree/xray/src/main/java/scorekeep/GameModel.java) - 注释和元数据**  

```
import [com.amazonaws.xray.AWSXRay](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRay.html);
import [com.amazonaws.xray.entities.Segment](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/entities/Segment.html);
import [com.amazonaws.xray.entities.Subsegment](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/entities/Subsegment.html);
...
  public void saveGame(Game game) throws SessionNotFoundException {
    // wrap in subsegment
    Subsegment subsegment = AWSXRay.beginSubsegment("## GameModel.saveGame");
    try {
      // check session
      String sessionId = game.getSession();
      if (sessionModel.loadSession(sessionId) == null ) {
        throw new SessionNotFoundException(sessionId);
      }
      Segment segment = AWSXRay.getCurrentSegment();
      subsegment.putMetadata("resources", "game", game);
      segment.putAnnotation("gameid", game.getId());
      mapper.save(game);
    } catch (Exception e) {
      subsegment.addException(e);
      throw e;
    } finally {
      AWSXRay.endSubsegment();
    }
  }
```

## 使用 X-Ray SDK for Java 记录元数据


使用元数据记录有关您无需为其编制索引以进行搜索的分段或子分段的信息。元数据值可以是字符串、数字、布尔值或可序列化为 JSON 对象或数组的任何对象。

**记录元数据**

1. 从 `AWSXRay` 获取对当前分段或子分段的引用。

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

   或者

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

1. 调用带有字符串命名空间、字符串键和布尔值、数字值、字符串值或对象值的 `putMetadata`。

   ```
   document.putMetadata("my namespace", "my key", "my value");
   ```

   或者

   调用仅带有键和值的 `putMetadata`。

   ```
   document.putMetadata("my key", "my value");
   ```

如果您没有指定命名空间，则开发工具包将使用 `default`。使用相同键调用两次 `putMetadata` 将覆盖同一分段或子分段上之前记录的值。

**Example [https://github.com/awslabs/eb-java-scorekeep/tree/xray/src/main/java/scorekeep/GameModel.java](https://github.com/awslabs/eb-java-scorekeep/tree/xray/src/main/java/scorekeep/GameModel.java) - 注释和元数据**  

```
import [com.amazonaws.xray.AWSXRay](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRay.html);
import [com.amazonaws.xray.entities.Segment](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/entities/Segment.html);
import [com.amazonaws.xray.entities.Subsegment](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/entities/Subsegment.html);
...
  public void saveGame(Game game) throws SessionNotFoundException {
    // wrap in subsegment
    Subsegment subsegment = AWSXRay.beginSubsegment("## GameModel.saveGame");
    try {
      // check session
      String sessionId = game.getSession();
      if (sessionModel.loadSession(sessionId) == null ) {
        throw new SessionNotFoundException(sessionId);
      }
      Segment segment = AWSXRay.getCurrentSegment();
      subsegment.putMetadata("resources", "game", game);
      segment.putAnnotation("gameid", game.getId());
      mapper.save(game);
    } catch (Exception e) {
      subsegment.addException(e);
      throw e;
    } finally {
      AWSXRay.endSubsegment();
    }
  }
```

## 使用适用于 Java IDs 的 X-Ray SDK 录制用户


记录请求细分中的用户，以识别发送请求的用户。 IDs 

**要记录用户 IDs**

1. 从 `AWSXRay` 获取对当前分段的引用。

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

1. 使用发送请求的用户的字符串 ID 调用 `setUser`。

   ```
   document.setUser("U12345");
   ```

您可以在控制器中调用 `setUser` 以便在应用程序开始处理请求后立即记录用户 ID。如果您只打算使用分段来设置用户 ID，可以在单个行中链接这些调用。

**Example [src/main/java/scorekeep/MoveController.java](https://github.com/awslabs/eb-java-scorekeep/tree/xray/src/main/java/scorekeep/MoveController.java) — 用户 ID**  

```
import [com.amazonaws.xray.AWSXRay](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRay.html);
...
  @RequestMapping(value="/{userId}", method=RequestMethod.POST)
  public Move newMove(@PathVariable String sessionId, @PathVariable String gameId, @PathVariable String userId, @RequestBody String move) throws SessionNotFoundException, GameNotFoundException, StateNotFoundException, RulesException {
    AWSXRay.getCurrentSegment().setUser(userId);
    return moveFactory.newMove(sessionId, gameId, userId, move);
  }
```

要查找用户 ID 的跟踪，请在`user`筛选表达式[中使用 ](xray-console-filters.md) 关键字。

## Amazon X-Ray 适用于 Java 的 X-Ray SDK 的指标
监控

**注意**  
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)。

本主题介绍 Amazon X-Ray 命名空间、指标和维度。您可以使用适用于 Java 的 X-Ray SDK 从您收集的 X-Ray 细分中发布未采样的亚马逊 CloudWatch 指标。这些指标来自分段的开始和结束时间以及错误、故障和限制状态标志。使用这些指标可暴露子分段里的重试和依赖项问题。

CloudWatch 是一个指标存储库。指标是中的基本概念 CloudWatch ，代表一组按时间排序的数据点。您（或 Amazon Web Services 服务）将指标数据点发布到其中， CloudWatch 并将有关这些数据点的统计数据作为一组有序的时间序列数据进行检索。

指标通过名称、命名空间以及一个或多个维度进行唯一定义。每个数据点都有一个时间戳和一个可选的度量单位。当请求统计数据时，返回的数据流根据命名空间、指标名称和维度加以识别。

有关的更多信息 CloudWatch，请参阅 [https://docs.amazonaws.cn/AmazonCloudWatch/latest/DeveloperGuide/](https://docs.amazonaws.cn/AmazonCloudWatch/latest/DeveloperGuide/)。

### X-Ray CloudWatch 指标


`ServiceMetrics/SDK` 命名空间包括以下指标。


| 指标 | 可用统计数据 | 说明 | 单位 | 
| --- | --- | --- | --- | 
|  `Latency`  |  平均、最小、最大、计数  |  开始时间和结束时间之间的差异。平均、最小和最大都描述操作延迟。计数描述调用次数。  |  毫秒  | 
|  `ErrorRate`  |  平均、总计  |  导致错误的失败请求率，显示 `4xx Client Error` 状态码。  |  百分比  | 
|  `FaultRate`  |  平均、总计  |  导致故障的失败跟踪率，显示 `5xx Server Error` 状态码。  |  百分比  | 
|  `ThrottleRate`  |  平均、总计  |  返回 `429` 状态码的受限制跟踪率。这是 `ErrorRate` 指标的子集。  |  百分比  | 
|  `OkRate`  |  平均、总计  |  导致 `OK` 状态码的被跟踪请求率。  |  百分比  | 

### X 射线 CloudWatch 尺寸


您可以用下表中的维度来优化针对经 X-Ray 检测的 Java 应用程序返回的指标。


| 维度 | 说明 | 
| --- | --- | 
|  `ServiceType`  |  服务类型，例如 `AWS::EC2::Instance` 或 `NONE`（如果为未知）。  | 
|  `ServiceName`  |  服务的规范名称。  | 

### 启用 X-Ray CloudWatch 指标


使用以下过程在已检测的 Java 应用程序中启用跟踪指标。

**配置跟踪指标**

1. 将 `aws-xray-recorder-sdk-metrics` 包添加为 Apache Maven 依赖项。有关更多信息，请参阅 [X-Ray SDK for Java Submodules](#xray-sdk-java-submodules)。

1. 启用新的 `MetricsSegmentListener()` 作为全局记录器构建的一部分。  
**Example src/com/myapp/web/Startup.java**  

   ```
   import com.amazonaws.xray.AWSXRay;
   import com.amazonaws.xray.AWSXRayRecorderBuilder;
   import com.amazonaws.xray.plugins.EC2Plugin;
   import com.amazonaws.xray.plugins.ElasticBeanstalkPlugin;
   import com.amazonaws.xray.strategy.sampling.LocalizedSamplingStrategy;
   
   @Configuration
   public class WebConfig {
   ...
     static {
       AWSXRayRecorderBuilder builder = AWSXRayRecorderBuilder
                                           .standard()
                                           .withPlugin(new EC2Plugin())
                                           .withPlugin(new ElasticBeanstalkPlugin())
                                           .withSegmentListener(new MetricsSegmentListener());
   
       URL ruleFile = WebConfig.class.getResource("/sampling-rules.json");
       builder.withSamplingStrategy(new LocalizedSamplingStrategy(ruleFile));
   
       AWSXRay.setGlobalRecorder(builder.build());
     }
   }
   ```

1. 部署 CloudWatch 代理以使用亚马逊弹性计算云（亚马逊 EC2）、亚马逊弹性容器服务（亚马逊 ECS）或亚马逊 Elastic Kubernetes Service（亚马逊 EKS）收集指标：
   +  要配置 Amazon EC2，请参阅[安装 CloudWatch 代理](https://docs.amazonaws.cn/AmazonCloudWatch/latest/monitoring/install-CloudWatch-Agent-on-EC2-Instance.html)。
   +  要配置 Amazon ECS，请参阅[使用 Container Insights 监控 Amazon ECS 容器](https://docs.amazonaws.cn/AmazonECS/latest/developerguide/cloudwatch-container-insights.html)
   +  要配置 Amazon EKS，请参阅[使用 Amazon Obs CloudWatch ervability EKS 插件安装 CloudWatch 代理](https://docs.amazonaws.cn/AmazonCloudWatch/latest/monitoring/install-CloudWatch-Observability-EKS-addon.html)。

1. 将 SDK 配置为与 CloudWatch 代理通信。默认情况下，SDK 通过地址`127.0.0.1`与 CloudWatch 代理进行通信。您可以通过将环境变量或 Java 属性设置为 `address:port` 来配置备用地址。  
**Example 环境变量**  

   ```
   AWS_XRAY_METRICS_DAEMON_ADDRESS=address:port
   ```  
**Example Java 属性**  

   ```
   com.amazonaws.xray.metrics.daemonAddress=address:port
   ```

**验证配置**

1. 登录 Amazon Web Services 管理控制台 并打开 CloudWatch 控制台，网址为[https://console.aws.amazon.com/cloudwatch/](https://console.amazonaws.cn/cloudwatch/)。

1. 打开**指标**选项卡以观察指标的情况。

1. （可选）在 CloudWatch 控制台的**日志**选项卡上，打开`ServiceMetricsSDK`日志组。查找与主机指标相匹配的日志流，然后确认日志消息。

# 在多线程应用程序中的线程之间传递分段上下文
多线程处理

**注意**  
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)。

在您的应用程序中创建新线程时，`AWSXRayRecorder` 不会维护对当前分段或子分段[实体](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/entities/Entity.html)的引用。如果您在新话题中使用经过检测的客户端，SDK 会尝试写入不存在的区段，从而导致 [SegmentNotFoundException](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/exceptions/SegmentNotFoundException.html).

为避免在开发过程中抛出异常，您可以为记录器配置一个[ContextMissingStrategy](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/strategy/ContextMissingStrategy.html)提醒它记录错误的。您可以使用代码配置策略 [SetContextMissingStrategy](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRayRecorder.html#setContextMissingStrategy(com.amazonaws.xray.strategy.ContextMissingStrategy))，也可以使用[环境变量](xray-sdk-java-configuration.md#xray-sdk-java-configuration-envvars)或[系统属性](xray-sdk-java-configuration.md#xray-sdk-java-configuration-sysprops)配置等效选项。

解决错误的一种方法是使用新分段：在您启动线程时调用 [beginSegment](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRayRecorder.html#beginSegment(java.lang.String))，并在您将其关闭时调用 [endSegment](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRayRecorder.html#endSegment--)。如果您正在检测并非为响应 HTTP 请求而运行的代码，例如在您的应用程序启动时运行的代码，这很适合。

如果您使用多个线程来处理传入请求，您可以将当前分段或子分段传递到新线程，并将其提供给全局记录器。这样可以确保对于新线程中记录的信息，相关联的分段与针对该请求记录的其余信息的关联分段相同。一旦分段在新线程中可用，即可执行任何可使用 `segment.run(() -> { ... })` 方法访问该分段的上下文的可运行。

有关示例，请参阅 [在工作线程中使用检测的客户端](scorekeep-workerthreads.md)。

## 使用 X-Ray 进行异步编程


 适用于 Java 的 X-Ray SDK 可以在异步 Java 程序中使用[SegmentContextExecutors](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/contexts/SegmentContextExecutors.html)。 SegmentContextExecutor 实现了 Executor 接口，这意味着它可以传递到 a [CompletableFuture](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html)的所有异步操作中。这样可以确保任何异步操作都将在其上下文中使用正确的分段执行。

**Example 示例 App.java：传递 SegmentContextExecutor 给 CompletableFuture**  

```
DynamoDbAsyncClient client = DynamoDbAsyncClient.create();

AWSXRay.beginSegment();

// ...

client.getItem(request).thenComposeAsync(response -> {
    // If we did not provide the segment context executor, this request would not be traced correctly.
    return client.getItem(request2);
}, SegmentContextExecutors.newSegmentContextExecutor());
```

# 包含 Spring 以及适用于 Java 的 X-Ray 开发工具包的 AOP
Spring 中的 AOP

**注意**  
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)。

本主题介绍如何使用 X-Ray 开发工具包和 Spring Framework 检测应用程序，而不更改其核心逻辑。这意味着现在有一种非侵入性的方法可以检测远程运行的应用程序。 Amazon

**启用 Spring 中的 AOP**

1. [配置 Spring](#xray-sdk-java-aop-spring-configuration)

1. [向应用程序添加跟踪筛选器](#xray-sdk-java-aop-filters-spring)

1. [对代码添加注释或实现接口](#xray-sdk-java-aop-annotate-or-implement)

1. [激活应用程序中的 X-Ray](#xray-sdk-java-aop-activate-xray)

## 配置 Spring


您可以使用 Maven 或 Gradle 将 Spring 配置为使用 AOP 检测您的应用程序。

如果您使用 Maven 来生成应用程序，则在 `pom.xml` 文件中添加以下依赖项。

```
<dependency> 
     <groupId>com.amazonaws</groupId> 
     <artifactId>aws-xray-recorder-sdk-spring</artifactId> 
     <version>2.11.0</version> 
</dependency>
```

对于 Gradle，在 `build.gradle` 文件中添加以下依赖项。

```
compile 'com.amazonaws:aws-xray-recorder-sdk-spring:2.11.0'
```

## 配置 Spring Boot


除了上一节中介绍的 Spring 依赖项，如果您使用的是 Spring Boot，如果尚位在类路径上，请添加以下依赖项。

Maven：

```
<dependency> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-aop</artifactId> 
     <version>2.5.2</version> 
</dependency>
```

Gradle：

```
compile 'org.springframework.boot:spring-boot-starter-aop:2.5.2'
```

## 向应用程序添加跟踪筛选器


将 `Filter` 添加到 `WebConfig` 类。将分段名称作为字符串传递到 [https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/javax/servlet/AWSXRayServletFilter.html](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/javax/servlet/AWSXRayServletFilter.html) 构造函数。有关跟踪筛选器和检测传入请求的更多信息，请参阅 [使用适用于 Java 的 X-Ray 开发工具包跟踪传入请求](xray-sdk-java-filters.md)。

**Example src/main/java/myapp/WebConfig.java-春季**  

```
package myapp;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Bean;
import javax.servlet.Filter;
import [com.amazonaws.xray.javax.servlet.AWSXRayServletFilter](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/javax/servlet/AWSXRayServletFilter.html);

@Configuration
public class WebConfig {

  @Bean
  public Filter TracingFilter() {
    return new AWSXRayServletFilter("Scorekeep");
  }
}
```

## Jakarta 支持


 Spring 6 企业版使用 [Jakarta](https://spring.io/blog/2022/11/16/spring-framework-6-0-goes-ga) 而非 Java。为支持这一全新命名空间，X-Ray 创建出位于其自己 Jakarta 命名空间里的类的并行集。

对于筛选器类，将 `javax` 替换为 `jakarta`。配置分段命名策略时，如下所示，在命名策略类名称前添加 `jakarta`：

```
package myapp;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Bean;
import jakarta.servlet.Filter;
import com.amazonaws.xray.jakarta.servlet.AWSXRayServletFilter;
import com.amazonaws.xray.strategy.jakarta.SegmentNamingStrategy;

@Configuration
public class WebConfig {
    @Bean
    public Filter TracingFilter() {
        return new AWSXRayServletFilter(SegmentNamingStrategy.dynamic("Scorekeep"));
    }
}
```

## 对代码添加注释或实现接口


您的类必须使用 `@XRayEnabled` 注释添加注释，或实现 `XRayTraced` 接口。这将告知 AOP 系统包装受影响类的函数以进行 X-Ray 检测。

## 激活应用程序中的 X-Ray


要激活应用程序中的 X-Ray 跟踪，您的代码必须通过覆盖以下方法来扩展抽象类 `BaseAbstractXRayInterceptor`。
+ `generateMetadata` - 此函数允许对附加到当前函数跟踪的元数据进行自定义。默认情况下，执行函数的类名将记录在元数据中。如果您需要其他信息，则可添加更多数据。
+ `xrayEnabledClasses` - 此函数为空，并且应保持此状态。它用作告知拦截程序要包装的方法的指示的主机。通过指定使用要跟踪的 `@XRayEnabled` 添加注释的类来定义指示。以下指示语句告知拦截程序包装使用 `@XRayEnabled` 注释添加注释的所有控制器 bean。

  ```
  @Pointcut(“@within(com.amazonaws.xray.spring.aop.XRayEnabled) && bean(*Controller)”)
  ```

 如果项目使用的是 Spring Data JPA，请考虑从 `AbstractXRayInterceptor` 而非 `BaseAbstractXRayInterceptor` 进行扩展。

## 示例


以下代码扩展抽象类 `BaseAbstractXRayInterceptor`。

```
@Aspect
@Component
public class XRayInspector extends BaseAbstractXRayInterceptor {    
    @Override    
    protected Map<String, Map<String, Object>> generateMetadata(ProceedingJoinPoint proceedingJoinPoint, Subsegment subsegment) throws Exception {      
        return super.generateMetadata(proceedingJoinPoint, subsegment);    
    }    
  
  @Override    
  @Pointcut("@within(com.amazonaws.xray.spring.aop.XRayEnabled) && bean(*Controller)")    
  public void xrayEnabledClasses() {}
  
}
```

以下代码是一个将由 X-Ray 检测的类。

```
@Service
@XRayEnabled
public class MyServiceImpl implements MyService {    
    private final MyEntityRepository myEntityRepository;    
    
    @Autowired    
    public MyServiceImpl(MyEntityRepository myEntityRepository) {        
        this.myEntityRepository = myEntityRepository;    
    }    
    
    @Transactional(readOnly = true)    
    public List<MyEntity> getMyEntities(){        
        try(Stream<MyEntity> entityStream = this.myEntityRepository.streamAll()){            
            return entityStream.sorted().collect(Collectors.toList());        
        }    
    }
}
```

如果您已正确配置您的应用程序，则应看到应用程序的完整调用堆栈（从控制器向下至服务调用），如以下控制台屏幕截图所示。

![\[Timeline showing API call duration and breakdown of server operations for metering service.\]](http://docs.amazonaws.cn/xray/latest/devguide/images/aop-spring-console.png)
