

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

# Amazon 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)。

上 GitHub提供的 Amazon X-Ray [eb-java-scorekeep](https://github.com/awslabs/eb-java-scorekeep/tree/xray)示例应用程序展示了如何使用 Amazon X-Ray SDK 来检测传入的 HTTP 调用、DynamoDB SDK 客户端和 HTTP 客户端。该示例应用程序用于 Amazon CloudFormation 创建 DynamoDB 表、在实例上编译 Java 代码以及运行 X-Ray 守护程序，无需任何其他配置。

请参阅 [Scorekeeep 教程](scorekeep-tutorial.md)，使用或开始安装和使用带检测功能的 Amazon Web Services 管理控制台 示例应用程序。 Amazon CLI

![\[Scorekeep 使用 Amazon X-Ray SDK 来检测传入的 HTTP 调用、DynamoDB SDK 客户端和 HTTP 客户端\]](http://docs.amazonaws.cn/xray/latest/devguide/images/scorekeep-flow.png)


该示例包括前端 Web 应用程序、所调用的 API 以及它用于存储数据的 DynamoDB 表。包含[过滤器](xray-sdk-java-filters.md)、[插件](xray-sdk-java-configuration.md)和[经过检测的 Amazon SDK 客户端](xray-sdk-java-awssdkclients.md)的基本插件显示在项目的`xray-gettingstarted`分支中。这是您在[入门教程](scorekeep-tutorial.md)中部署的分支。由于此分支只包含基本分析，您可以根据 `master` 分支比较差异，以快速理解基本分析。

![\[Service map showing client interaction with Scorekeep container and related Amazon Web Services 服务.\]](http://docs.amazonaws.cn/xray/latest/devguide/images/scorekeep-gettingstarted-servicemap-before-ECS.png)


该应用程序示例在这些文件中显示基本检测：
+ **HTTP 请求筛选器** - [https://github.com/awslabs/eb-java-scorekeep/tree/xray/src/main/java/scorekeep/WebConfig.java](https://github.com/awslabs/eb-java-scorekeep/tree/xray/src/main/java/scorekeep/WebConfig.java)
+ **Amazon SDK 客户端工具** — [https://github.com/awslabs/eb-java-scorekeep/tree/xray/build.gradle](https://github.com/awslabs/eb-java-scorekeep/tree/xray/build.gradle)

该应用程序的`xray`分支包括使用[注释[HTTPClient](xray-sdk-java-httpclients.md)](xray-sdk-java-segment.md)、[SQL 查询](xray-sdk-java-sqlclients.md)、[自定义子分段](xray-sdk-java-subsegments.md)、检测[Amazon Lambda](xray-services-lambda.md)函数以及检测过的[初始化代码和脚](scorekeep-startup.md)本。

为了支持用户登录和在浏览器中 适用于 JavaScript 的 Amazon SDK 使用，该`xray-cognito`分支机构添加了 Amazon Cognito 来支持用户身份验证和授权。利用从 Amazon Cognito 检索到的凭证，Web 应用程序还会将跟踪数据发送到 X-Ray，以从客户端的视角记录请求信息。浏览器客户端在跟踪地图中显示为自己的节点，并记录其他信息，包括用户正在查看的页面的 URL 和用户的 ID。

最后，`xray-worker` 分支将添加独立运行的检测过的 Lambda 函数，并处理来自 Amazon SQS 队列的项目。每当游戏结束时，Scorekeep 就会向队列添加一个项目。由 CloudWatch 事件触发的 Lambda 工作程序每隔几分钟从队列中提取项目，然后对其进行处理，以便将游戏记录存储在 Amazon S3 中以供分析。

**Topics**
+ [

# Scorekeep 示例应用程序入门
](scorekeep-tutorial.md)
+ [

# 手动检测 S Amazon DK 客户端
](scorekeep-sdkclients.md)
+ [

# 创建附加子分段
](scorekeep-subsegments.md)
+ [

# 记录注释、元数据和用户 IDs
](scorekeep-annotations.md)
+ [

# 检测传出 HTTP 调用
](scorekeep-httpclient.md)
+ [

# 检测对 PostgreSQL 数据库的调用
](scorekeep-postgresql.md)
+ [

# 仪表函数 Amazon Lambda
](scorekeep-lambda.md)
+ [

# 检测启动代码
](scorekeep-startup.md)
+ [

# 检测脚本
](scorekeep-scripts.md)
+ [

# 检测 Web 应用程序客户端
](scorekeep-client.md)
+ [

# 在工作线程中使用检测的客户端
](scorekeep-workerthreads.md)

# Scorekeep 示例应用程序入门
Scorekeep 教程

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

本教程使用 [Scorekeeep 示例应用程序](xray-scorekeep.md)的`xray-gettingstarted`分支，该分支用于 Amazon CloudFormation 创建和配置在 Amazon ECS 上运行示例应用程序和 X-Ray 守护程序的资源。该应用程序使用 Spring 框架来实现 JSON Web API，并使用将数据保存 适用于 Java 的 Amazon SDK 到 Amazon DynamoDB。应用程序中的 servlet 过滤器会检测应用程序处理的所有传入请求，而 Amazon SDK 客户端上的请求处理程序则用于监测 DynamoDB 的下游调用。

您可以使用 Amazon Web Services 管理控制台 或来学习本教程 Amazon CLI。

**Topics**
+ [

## 先决条件
](#xray-gettingstarted-prereqs)
+ [

## 使用以下命令安装 Scorekeeep 应用程序 CloudFormation
](#xray-gettingstarted-deploy)
+ [

## 生成跟踪数据
](#xray-gettingstarted-generate-traces)
+ [

## 在中查看追踪地图 Amazon Web Services 管理控制台
](#xray-gettingstarted-console)
+ [

## 配置 Amazon SNS 通知
](#xray-gettingstarted-notifications)
+ [

## 浏览应用程序示例
](#xray-gettingstarted-sample)
+ [

## 可选：最低权限策略
](#xray-gettingstarted-security)
+ [

## 清理
](#xray-gettingstarted-cleanup)
+ [

## 后续步骤
](#xray-gettingstarted-nextsteps)

## 先决条件


本教程 Amazon CloudFormation 用于创建和配置运行示例应用程序和 X-Ray 守护程序的资源。安装和运行本教程需要满足以下先决条件：

1. 如果您使用权限有限的 IAM 用户，请在 [IAM 控制台](https://console.amazonaws.cn/iam)中添加以下用户策略：
   + `AWSCloudFormationFullAccess`— 访问和使用 CloudFormation
   + `AmazonS3FullAccess`— CloudFormation 使用将模板文件上传到 Amazon Web Services 管理控制台
   + `IAMFullAccess` — 用于创建 Amazon ECS 和 Amazon EC2 实例角色
   + `AmazonEC2FullAccess` — 用于创建 Amazon EC2 资源
   + `AmazonDynamoDBFullAccess` - 用于创建 DynamoDB 表
   + `AmazonECS_FullAccess` - 用于创建 Amazon ECS 资源
   + `AmazonSNSFullAccess` - 用于创建 Amazon SNS 主题
   + `AWSXrayReadOnlyAccess` - 用于查看 X-Ray 控制台中跟踪地图和跟踪的权限

1. 要使用完成本教程 Amazon CLI，[请安装 CLI](https://docs.amazonaws.cn/cli/latest/userguide/getting-started-install.html) 版本 2.7.9 或更高版本，并使用上一步中的用户[配置 CLI](https://docs.amazonaws.cn/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-config)。使用用户配置时，请确保已 Amazon CLI 配置区域。如果未配置区域，则需要将 `--region AWS-REGION` 附加到每一个 CLI 命令。

1. 确保已安装 [Git](https://github.com/git-guides/install-git)，以便克隆示例应用程序存储库。

1. 使用以下代码示例克隆 Scorekeep 存储库的 `xray-gettingstarted` 分支：

   ```
   git clone https://github.com/aws-samples/eb-java-scorekeep.git xray-scorekeep -b xray-gettingstarted
   ```

## 使用以下命令安装 Scorekeeep 应用程序 CloudFormation


------
#### [ Amazon Web Services 管理控制台 ]

**使用安装示例应用程序 Amazon Web Services 管理控制台**

1. 打开 [CloudFormation 控制台](https://console.amazonaws.cn/cloudformation/)

1. 选择**创建堆栈**，然后从下列菜单中选择**使用新资源**。

1. 在**指定模板**部分，选择**上传模板文件**。

1. 选择**选择文件**，导航到克隆 git 存储库时创建的 `xray-scorekeep/cloudformation` 文件夹，然后选择 `cf-resources.yaml` 文件。

1. 选择**下一步**以继续。

1. 在**堆栈名称**文本框中输入 `scorekeep`，然后选择页面底部的**下一步**以继续。请注意，本教程的其余部分假设堆栈已命名为 `scorekeep`。

1. 滚动到**配置堆栈选项**页面底部，选择**下一步**以继续。

1. 滚动到 “**查看**” 页面的底部，选中确认 CloudFormation 可以创建具有自定义名称的 IAM 资源的复选框，然后选择**创建堆栈**。

1.  CloudFormation 堆栈正在创建中。堆栈状态将在五分钟左右保持为 `CREATE_IN_PROGRESS`，然后变为 `CREATE_COMPLETE`。状态将会定期更新，也可以刷新页面。

------
#### [ Amazon CLI ]

**使用安装示例应用程序 Amazon CLI**

1. 导航到在教程更早时候克隆的 `cloudformation` 存储库的 `xray-scorekeep` 文件夹。

   ```
   cd xray-scorekeep/cloudformation/
   ```

1. 输入以下 Amazon CLI 命令来创建 CloudFormation 堆栈：

   ```
   aws cloudformation create-stack --stack-name scorekeep --capabilities "CAPABILITY_NAMED_IAM" --template-body file://cf-resources.yaml
   ```

1. 等到 CloudFormation 堆栈状态变为`CREATE_COMPLETE`，大约需要五分钟。使用以下 Amazon CLI 命令检查状态：

   ```
   aws cloudformation describe-stacks --stack-name scorekeep --query "Stacks[0].StackStatus"
   ```

------

## 生成跟踪数据


示例应用程序包括一个前端 Web 应用程序。使用 Web 应用程序来生成 API 流量并将跟踪数据发送到 X-Ray。首先，使用 Amazon Web Services 管理控制台 或 Amazon CLI检索 Web 应用程序 URL：

------
#### [ Amazon Web Services 管理控制台 ]

**使用查找应用程序 URL Amazon Web Services 管理控制台**

1. 打开 [CloudFormation 控制台](https://console.amazonaws.cn/cloudformation/)

1. 从列表中选择 `scorekeep` 堆栈。

1. 在 `scorekeep` 堆栈页面上选择**输出**选项卡，然后选择 `LoadBalancerUrl` URL 链接打开 Web 应用程序。

------
#### [ Amazon CLI ]

**使用查找应用程序 URL Amazon CLI**

1. 使用以下命令显示 Web 应用程序的 URL：

   ```
   aws cloudformation describe-stacks --stack-name scorekeep --query "Stacks[0].Outputs[0].OutputValue"
   ```

1. 复制此 URL 并在浏览器中打开以显示 Scorekeep Web 应用程序。

------

**使用 Web 应用程序生成跟踪数据**

1. 选择 **Create** 来创建用户和会话。

1. 键入**游戏名称**，将**规则**设置为 **Tic Tac Toe**，然后选择**创建**来创建一个游戏。

1. 选择 **Play** 以启动游戏。

1. 选择平铺可进行移动和更改游戏状态。

上述每个步骤都会生成到 API 的 HTTP 请求，并对 DynamoDB 进行下游调用，以读取和写入用户、会话、游戏、移动和状态数据。

## 在中查看追踪地图 Amazon Web Services 管理控制台


您可以在 X-Ray 和 CloudWatch 控制台中查看示例应用程序生成的轨迹图和轨迹。

------
#### [ X-Ray console ]

**使用 X-Ray 控制台**

1. 打开 [X-Ray 控制台](https://console.amazonaws.cn/xray/home#/service-map)的跟踪地图页面。

1. 控制台将显示该服务的图形表示形式，这是由 X-Ray 利用应用程序发送的跟踪数据生成的。需要时，务必调整跟踪地图的时间段，以确保将会显示自您首次启动该 Web 应用程序以来的所有跟踪。  
![\[X-Ray 跟踪地图时间段\]](http://docs.amazonaws.cn/xray/latest/devguide/images/xray-console-time-period-15-minutes.png)

该跟踪地图显示 Web 应用程序客户端、在 Amazon ECS 中运行的 API，以及应用程序使用的每个 DynamoDB 表。对应用程序的每个请求（最多为可配置的每秒最大请求数）都受到跟踪（因为请求到达 API），生成针对下游服务的请求，然后完成。

可以在服务图中选择任一节点，来查看对该节点生成流量的请求的跟踪。目前，Amazon SNS 节点显示为黄色。深入了解原因。

![\[X-Ray 控制台跟踪地图页面\]](http://docs.amazonaws.cn/xray/latest/devguide/images/scorekeep-gettingstarted-servicemap-before-ECS.png)


**查找错误原因**

1. 选择名为 **SNS** 的节点。将会显示该节点的详细信息面板。

1. 选择**查看跟踪**以访问**跟踪概述**屏幕。

1. 从**跟踪列表**中选择跟踪。该跟踪没有方法或 URL，因为它是在启动期间记录的，而不是对传入请求的响应。  
![\[从跟踪列表中选择跟踪\]](http://docs.amazonaws.cn/xray/latest/devguide/images/scorekeep-gettingstarted-tracelist-sns.png)

1. 选择页面底部 Amazon SNS 分段中的错误状态图标，打开 SNS 子分段的**异常**页面。  
![\[选择错误状态图标以打开 Amazon SNS 子分段的“异常”页面。\]](http://docs.amazonaws.cn/xray/latest/devguide/images/scorekeep-gettingstarted-timeline-sns-ecs.png)

1. X-Ray SDK 会自动捕获由已检测的 Amazon SDK 客户端引发的异常并记录堆栈跟踪。  
![\[显示捕获的异常和记录的堆栈跟踪的“异常”选项卡\]](http://docs.amazonaws.cn/xray/latest/devguide/images/scorekeep-gettingstarted-exception.png)

------
#### [ CloudWatch console ]

**使用控制 CloudWatch 台**

1. 打开 CloudWatch 控制台的 [X-Ray 跟踪地图](https://console.amazonaws.cn/cloudwatch/home#xray:service-map/map)页面。

1. 控制台将显示该服务的图形表示形式，这是由 X-Ray 利用应用程序发送的跟踪数据生成的。需要时，务必调整跟踪地图的时间段，以确保将会显示自您首次启动该 Web 应用程序以来的所有跟踪。  
![\[CloudWatch 追踪地图时间段\]](http://docs.amazonaws.cn/xray/latest/devguide/images/cw-console-service-map-time-period-15-minutes.png)

该跟踪地图显示 Web 应用程序客户端、在 Amazon EC2 中运行的 API，以及应用程序使用的每个 DynamoDB 表。对应用程序的每个请求（最多为可配置的每秒最大请求数）都受到跟踪（因为请求到达 API），生成针对下游服务的请求，然后完成。

可以在服务图中选择任一节点，来查看对该节点生成流量的请求的跟踪。目前，Amazon SNS 节点显示为橙色。深入了解原因。

![\[X-Ray 控制台跟踪地图页面\]](http://docs.amazonaws.cn/xray/latest/devguide/images/scorekeep-gettingstarted-cw-servicemap-before-ECS.png)


**查找错误原因**

1. 选择名为 **SNS** 的节点。地图下方显示 SNS 节点详细信息面板。

1. 选择**查看跟踪**以访问**跟踪**页面。

1. 添加页面底部，从**跟踪**列表中选择跟踪。该跟踪没有方法或 URL，因为它是在启动期间记录的，而不是对传入请求的响应。  
![\[从跟踪列表中选择跟踪\]](http://docs.amazonaws.cn/xray/latest/devguide/images/scorekeep-gettingstarted-cw-tracelist-sns-ecs.png)

1. 在分段时间线底部选择 Amazon SNS 子分段，然后选择该 SNS 子分段的**异常**选项卡以查看异常详细信息。  
![\[查看 Amazon SNS 子分段的“异常”选项卡\]](http://docs.amazonaws.cn/xray/latest/devguide/images/scorekeep-gettingstarted-cw-timeline-sns-ecs.png)

------

原因指出，在 `WebConfig` 类中，调用 `createSubscription` 时所提供的电子邮件地址无效。在下一节中，我们将会修复此问题。

## 配置 Amazon SNS 通知


当用户完成游戏时，Scorekeep 使用 Amazon SNS 发送通知。当应用程序启动时，它会尝试为 CloudFormation 堆栈参数中定义的电子邮件地址创建订阅。该调用目前会失败。配置通知电子邮件以启用通知，并处理跟踪地图中突出显示的失败。

------
#### [ Amazon Web Services 管理控制台 ]

**要使用配置亚马逊 SNS 通知 Amazon Web Services 管理控制台**

1. 打开 [CloudFormation 控制台](https://console.amazonaws.cn/cloudformation/)

1. 在列表中选择 `scorekeep` 堆栈名称旁边的单选按钮，然后选择**更新**。

1. 确保选择的是**用户当前模板**，然后单击****更新堆栈页面上的**下一步**。

1. 在列表中找到**电子邮件**参数，将默认值替换为有效的电子邮件地址。  
![\[更新电子邮件配置\]](http://docs.amazonaws.cn/xray/latest/devguide/images/scorekeep-cf-email-update.png)

1. 滚动到页面底部并选择**下一步**。

1. 滚动到 “**查看**” 页面的底部，选中确认 CloudFormation 可以创建具有自定义名称的 IAM 资源的复选框，然后选择 **Update stack**。

1.  CloudFormation 堆栈现在正在更新中。堆栈状态将在五分钟左右保持为 `UPDATE_IN_PROGRESS`，然后变为 `UPDATE_COMPLETE`。状态将会定期更新，也可以刷新页面。

------
#### [ Amazon CLI ]

**要使用配置亚马逊 SNS 通知 Amazon CLI**

1. 导航到之前创建的 `xray-scorekeep/cloudformation/` 文件夹，然后在文本编辑器打开 `cf-resources.yaml` 文件。

1. 在 “**电子邮件**” 参数中找到该`Default`值，然后将其从更改*UPDATE\$1ME*为有效的电子邮件地址。

   ```
   Parameters:
     Email:
       Type: String
       Default: UPDATE_ME # <- change to a valid abc@def.xyz email address
   ```

1. 在`cloudformation`文件夹中，使用以下 Amazon CLI 命令更新 CloudFormation 堆栈：

   ```
   aws cloudformation update-stack --stack-name scorekeep --capabilities "CAPABILITY_NAMED_IAM" --template-body file://cf-resources.yaml
   ```

1. 等到 CloudFormation 堆栈状态变为`UPDATE_COMPLETE`，这将需要几分钟。使用以下 Amazon CLI 命令检查状态：

   ```
   aws cloudformation describe-stacks --stack-name scorekeep --query "Stacks[0].StackStatus"
   ```

------

更新完成后，Scorekeep 重新启动并创建对 SNS 主题的订阅。当您完成游戏时，检查电子邮件并确认订阅以查看更新。打开跟踪地图，验证对 SNS 的调用不再失败。

## 浏览应用程序示例


在 Java 中，应用程序示例是一个 HTTP Web API，可配置为使用 X-Ray SDK for Java。当您使用 CloudFormation 模板部署应用程序时，它会创建 DynamoDB 表、Amazon ECS 集群以及在 ECS 上运行 Scorekeep 所需的其他服务。ECS 的任务定义文件是通过创建的 CloudFormation。此文件定义 ECS 集群中每项任务使用的容器映像。这些映像从官方 X-Ray 公共 ECR 中获取。Scorekeep API 容器映像具有兼容 Gradle 的 API。Scorekeeep 前端容器的容器映像充当使用 nginx 代理服务器的前端。此服务器会将传送到以 /api 开头的路径的请求路由到 API。

要检测传入 HTTP 请求，应用程序将添加 SDK 提供的 `TracingFilter`。

**Example src/main/java/scorekeep/WebConfig.java-servlet 过滤器**  

```
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");
  }
...
```

此筛选器会发送有关应用程序所处理所有传入请求的跟踪数据，包括请求 URL、方法、响应状态、开始时间和结束时间。

应用程序还会使用 适用于 Java 的 Amazon SDK对 DynamoDB 进行下游调用。要检测这些调用，应用程序只需将与 Amazon SDK 相关的子模块作为依赖项，适用于 Java 的 X-Ray SDK 会自动检测所有 Amazon SDK 客户端。

应用程序使用 `Docker` 在实例上生成源代码，使用 `Gradle Docker Image` 和 `Scorekeep API Dockerfile` 文件运行 Gradle 在其 `ENTRYPOINT` 生成的可执行 JAR。

**Example 使用 Docker 通过 Gradle Docker 映像进行构建**  

```
docker run --rm -v /PATH/TO/SCOREKEEP_REPO/home/gradle/project -w /home/gradle/project gradle:4.3 gradle build
```

**Example Dockerfile ENTRYPOINT**  

```
ENTRYPOINT [ "sh", "-c", "java -Dserver.port=5000 -jar scorekeep-api-1.0.0.jar" ]
```

在编译期间，`build.gradle` 从 Maven 下载 SDK 子模块，方法是将这些子模块声明为依赖项。

**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")
    ...
}
dependencyManagement {
    imports {
        mavenBom("com.amazonaws:aws-java-sdk-bom:1.11.67")
        mavenBom("com.amazonaws:aws-xray-recorder-sdk-bom:2.11.0")
    }
}
```

核心、 Amazon SDK 和 S Amazon DK Instrumentor 子模块就是自动检测使用 SDK 进行的任何下游调用所 Amazon 必需的。

如需将原始分段数据中断到 X-Ray API，则需要使用 X-Ray 进程守护程序侦听流量或 UDP 端口 2000。为此，应用程序让 X-Ray 进程守护程序在 ECS 上作为*附加容器*与 Scorekeep 应用程序一起部署的容器中运行。请参阅 [X-Ray 进程守护程序](xray-daemon.md)主题了解更多信息。

**Example ECS 任务定义中的 X-Ray 进程守护程序容器定义。**  

```
...
Resources:
  ScorekeepTaskDefinition:
    Type: AWS::ECS::TaskDefinition
    Properties: 
      ContainerDefinitions: 
      ...
      
      - Cpu: '256'
        Essential: true
        Image: amazon/aws-xray-daemon
        MemoryReservation: '128'
        Name: xray-daemon
        PortMappings: 
          - ContainerPort: '2000'
            HostPort: '2000'
            Protocol: udp
      ...
```

X-Ray SDK for Java 提供了一个名为 `AWSXRay` 的类，该类提供全局记录器，即您可用于检测代码的 `TracingHandler`。您可以配置全局记录器以自定义为传入 HTTP 调用创建分段的 `AWSXRayServletFilter`。示例包括 `WebConfig` 类中的一个静态数据块，该数据块使用插件和示例规则配置全局记录器。

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

```
import com.amazonaws.xray.AWSXRay;
import com.amazonaws.xray.AWSXRayRecorderBuilder;
import com.amazonaws.xray.javax.servlet.AWSXRayServletFilter;
import com.amazonaws.xray.plugins.ECSPlugin;
import com.amazonaws.xray.plugins.EC2Plugin;
import com.amazonaws.xray.strategy.sampling.LocalizedSamplingStrategy;
...

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

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

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

该示例使用生成器加载来自名为 `sampling-rules.json` 的文件的采样规则。采样规则确定 SDK 记录传入请求分段的速率。

**Example src/main/java/resources/sampling-rules.json**  

```
{
  "version": 1,
  "rules": [
    {
      "description": "Resource creation.",
      "service_name": "*",
      "http_method": "POST",
      "url_path": "/api/*",
      "fixed_target": 1,
      "rate": 1.0
    },
    {
      "description": "Session polling.",
      "service_name": "*",
      "http_method": "GET",
      "url_path": "/api/session/*",
      "fixed_target": 0,
      "rate": 0.05
    },
    {
      "description": "Game polling.",
      "service_name": "*",
      "http_method": "GET",
      "url_path": "/api/game/*/*",
      "fixed_target": 0,
      "rate": 0.05
    },
    {
      "description": "State polling.",
      "service_name": "*",
      "http_method": "GET",
      "url_path": "/api/state/*/*/*",
      "fixed_target": 0,
      "rate": 0.05
    }
  ],
  "default": {
    "fixed_target": 1,
    "rate": 0.1
  }
}
```

采样规则文件定义了四个自定义采样规则和默认规则。对于每个传入请求，SDK 按定义的顺序评估自定义规则。SDK 应用与请求的方法、路径和服务名称匹配的第一个规则。对于 Scorekeep，第一个规则通过应用每秒 1 个请求的固定目标和 1.0 的速率来捕获所有 POST 请求 (资源创建调用)，或者，在满足固定目标后，捕获 100% 的请求。

另外三个自定义规则应用 5% 的速率，对于会话、游戏和状态读取无固定目标（GET 请求）。这样可以尽可能减少前端为确保内容最新而每隔几秒钟自动发出的定期调用的跟踪数。对于所有其他请求，该文件定义默认速率为每秒 1 个请求，速率为 10%。

示例应用程序还展示了如何使用高级特征，如手动 SDK 客户端检测、创建其他子分段和传出 HTTP 调用。有关更多信息，请参阅 [Amazon X-Ray 示例应用程序](xray-scorekeep.md)。

## 可选：最低权限策略


 Scorekeeep ECS 容器使用 `AmazonSNSFullAccess` 和 `AmazonDynamoDBFullAccess` 等完整访问策略来访问资源。对于生产应用程序而言，使用完整访问策略并不是最佳做法。以下示例更新 DynamoDB IAM 策略以提升应用程序的安全性。要详细了解 IAM 策略中的安全最佳实践，请参阅 [Amazon X-Ray 的身份和访问管理](security-iam.md)。

**Example cf-resources.yaml 模板角色定义 ECSTask**  

```
ECSTaskRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"		 	 	 
        Statement: 
          - 
            Effect: "Allow"
            Principal: 
              Service: 
                - "ecs-tasks.amazonaws.com"
            Action: 
              - "sts:AssumeRole"
      ManagedPolicyArns:
        - "arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess"
        - "arn:aws:iam::aws:policy/AmazonSNSFullAccess"
        - "arn:aws:iam::aws:policy/AWSXrayFullAccess"
      RoleName: "scorekeepRole"
```

要更新策略，您首先需要确定 DynamoDB 资源的 ARN。然后，使用自定义 IAM 策略中的 ARN。最后，将该策略应用到实例配置文件。

**如何识别 DynamoDB 资源的 ARN：**

1. 打开 [DynamoDB 控制台](https://console.amazonaws.cn/dynamodbv2)。

1. 从左侧导航栏中选择**表**。

1. 选择任意一个 `scorekeep-*` 显示表的详细信息页面。

1. 在**概述**选项卡下，选择**其他信息**展开此部分，查看 Amazon 资源名称（ARN）。复制该值。

1. 将 ARN 插入到以下 IAM 策略中，将 `AWS_REGION` 替换为具有您的具体区域和账户 ID 的 `AWS_ACCOUNT_ID` 值。此新策略仅允许执行指定的操作，而非允许执行任何操作的 `AmazonDynamoDBFullAccess` 策略。  
**Example**  

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Sid": "ScorekeepDynamoDB",
               "Effect": "Allow",
               "Action": [
                   "dynamodb:PutItem",
                   "dynamodb:UpdateItem",
                   "dynamodb:DeleteItem",
                   "dynamodb:GetItem",
                   "dynamodb:Scan",
                   "dynamodb:Query"
               ],
               "Resource": "arn:aws:dynamodb:us-east-1:111122223333:table/scorekeep-*"
           }
       ]
   }
   ```

------

   应用程序创建的表遵循一致的命名约定。可以使用 `scorekeep-*` 格式指示所有 Scorekeep 表。

**更改 IAM 策略**

1. 从 IAM 控制台打开 [Scorekeep 任务角色 (scorekeepRole)](https://console.amazonaws.cn/iamv2/home#/roles/details/scorekeepRole)。

1. 选择 `AmazonDynamoDBFullAccess` 策略旁边的复选框，然后选择**删除**以删除此策略。

1. 选择**添加权限**，然后选择**附加策略**，最后选择**创建策略**。

1. 选择 **JSON** 选项卡，然后粘贴上面创建的策略。

1. 在页面底部，选择**下一步：标签**。

1. 在页面底部，选择**下一步：查看**。

1. 在**名称**中，为策略分配一个名称。

1. 在页面底部，选择**创建策略**。

1. 将新创建的策略附加到 `scorekeepRole` 角色。附加的策略更改可能需要几分钟才能生效。

如果您已将新策略附加到该`scorekeepRole`角色，则必须在删除 CloudFormation 堆栈之前将其分离，因为此附加的策略将阻止堆栈被删除。删除此策略即可自动附加此策略。

**删除自定义 IAM 策略**

1. 打开 [IAM 控制台](https://console.amazonaws.cn/iam)。

1. 从左侧导航菜单中，选择**策略**。

1. 搜索在本节早些时候创建的自定义策略，然后选择策略名称旁边的单选按钮以突出显示它。

1. 选择**操作**下拉列表，然后选择**删除**。

1. 键入自定义策略的名称，然后选择**删除**以确认删除。此操作将会自动取消附加 `scorekeepRole` 角色中的策略。

## 清理


请按照以下步骤删除 Scorekeep 应用程序资源：

**注意**  
如果您使用本教程的前一部分创建并附加了自定义策略，则必须先从中移除策略，`scorekeepRole`然后才能删除 CloudFormation 堆栈。

------
#### [ Amazon Web Services 管理控制台 ]

**使用删除示例应用程序 Amazon Web Services 管理控制台**

1. 打开 [CloudFormation 控制台](https://console.amazonaws.cn/cloudformation/)

1. 在列表中选择 `scorekeep` 堆栈名称旁边的单选按钮，然后选择**删除**。

1.  CloudFormation 堆栈现在正在被删除。堆栈状态将会在几分钟内保持为 `DELETE_IN_PROGRESS`，直到所有资源被删除。状态将会定期更新，也可以刷新页面。

------
#### [ Amazon CLI ]

**使用删除示例应用程序 Amazon CLI**

1. 输入以下 Amazon CLI 命令以删除 CloudFormation 堆栈：

   ```
   aws cloudformation delete-stack --stack-name scorekeep
   ```

1. 等到 CloudFormation 堆栈不复存在，这大约需要五分钟。使用以下 Amazon CLI 命令检查状态：

   ```
   aws cloudformation describe-stacks --stack-name scorekeep --query "Stacks[0].StackStatus"
   ```

------

## 后续步骤


要了解有关 X-Ray 的更多信息，请参阅下一章[Amazon X-Ray 概念](xray-concepts.md)。

要测试你自己的应用程序，请详细了解适用于 Java 的 X-Ray SDK 或其他 X-Ray 中的一个 SDKs：
+ ** X-Ray SDK for Java** - [Amazon X-Ray 适用于 Java 的 SDK](xray-sdk-java.md)
+ ** X-Ray SDK for Node.js** - [Amazon 适用于 Node.js 的 X-ray SDK](xray-sdk-nodejs.md)
+ ** X-Ray SDK for .NET** - [Amazon X-Ray 适用于.NET 的 SDK](xray-sdk-dotnet.md)

要在本地或在本地运行 X-Ray 守护程序 Amazon，请参阅[Amazon X-Ray 守护程序](xray-daemon.md)。

要为上的示例应用程序做出贡献 GitHub，请参阅[eb-java-scorekeep](https://github.com/awslabs/eb-java-scorekeep/tree/xray-gettingstarted)。

# 手动检测 S Amazon DK 客户端
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)。

当你在[构建依赖项中包含 SDK Instrumentor 子模块时， Amazon 适用于 Java 的 X-Ray Amazon SDK](xray-sdk-java.md#xray-sdk-java-dependencies) 会自动检测所有 SDK 客户端。

您可以通过删除 Instrumentor 子模块来禁用自动客户端检测。这使您可以手动检测一些客户端而忽略另一些客户端，或者在不同客户端上使用不同跟踪处理程序。

为了说明对检测特定 S Amazon DK 客户端的支持，应用程序将跟踪处理程序`AmazonDynamoDBClientBuilder`作为用户、游戏和会话模型中的请求处理程序传递给。此代码更改告知 SDK 使用这些客户端检测对 DynamoDB 的所有调用。

**Example [https://github.com/awslabs/eb-java-scorekeep/tree/xray/src/main/java/scorekeep/SessionModel.java](https://github.com/awslabs/eb-java-scorekeep/tree/xray/src/main/java/scorekeep/SessionModel.java)— 手动 Amazon SDK 客户端工具**  

```
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 SessionModel {
  private AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard()
        .withRegion(Constants.REGION)
        .withRequestHandlers(new TracingHandler(AWSXRay.getGlobalRecorder()))
        .build();
  private DynamoDBMapper mapper = new DynamoDBMapper(client);
```

如果您从项目依赖项中移除 Amazon SDK Instrumentor 子模块，则只有手动检测的 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)。

在用户模型类中，应用程序需要手动创建子分段，以便对 `saveUser` 函数中执行的所有下游调用进行分组和添加元数据。

**Example [https://github.com/awslabs/eb-java-scorekeep/tree/xray/src/main/java/scorekeep/UserModel.java](https://github.com/awslabs/eb-java-scorekeep/tree/xray/src/main/java/scorekeep/UserModel.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.Subsegment](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/entities/Subsegment.html);
...
    public void saveUser(User user) {
    // Wrap in subsegment
    Subsegment subsegment = AWSXRay.beginSubsegment("## UserModel.saveUser");
    try {
      mapper.save(user);
    } catch (Exception e) {
      subsegment.addException(e);
      throw e;
    } finally {
      AWSXRay.endSubsegment();
    }
  }
```

# 记录注释、元数据和用户 IDs
注释和元数据

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

在游戏模型类中，每当应用程序将游戏保存在 DynamoDB 中时，都会将 `Game` 对象记录到[元数据](xray-sdk-java-segment.md#xray-sdk-java-segment-metadata)块中。另外，该应用程序将游戏记录 IDs 在[注释](xray-sdk-java-segment.md#xray-sdk-java-segment-annotations)中，以便与[过滤器表达式](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();
    }
  }
```

在移动控制器中，应用程序[ IDs使用记录用户](xray-sdk-java-segment.md#xray-sdk-java-segment-userid)`setUser`。用户 IDs被记录在区段的单独字段中，并编制索引以供搜索使用。

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

# 检测传出 HTTP 调用
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)。

用户工厂类显示应用程序如何使用 X-Ray SDK for Java 的 `HTTPClientBuilder` 版本来检测传出 HTTP 调用。

**Example [https://github.com/awslabs/eb-java-scorekeep/tree/xray/src/main/java/scorekeep/UserFactory.java](https://github.com/awslabs/eb-java-scorekeep/tree/xray/src/main/java/scorekeep/UserFactory.java)— HTTPClient 仪器**  

```
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://uinames.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();
    }
  }
```

如果您当前使用 `org.apache.http.impl.client.HttpClientBuilder`，则只需使用 `com.amazonaws.xray.proxies.apache.http.HttpClientBuilder` 的语句换出该类的导出语句。

# 检测对 PostgreSQL 数据库的调用
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)。

`application-pgsql.properties` 文件将 X-Ray PostgreSQL 跟踪拦截程序添加到在 [https://github.com/awslabs/eb-java-scorekeep/tree/xray/src/main/java/scorekeep/RdsWebConfig.java](https://github.com/awslabs/eb-java-scorekeep/tree/xray/src/main/java/scorekeep/RdsWebConfig.java) 中创建的数据源。

**Example [https://github.com/awslabs/eb-java-scorekeep/tree/xray/src/main/resources/application-pgsql.properties](https://github.com/awslabs/eb-java-scorekeep/tree/xray/src/main/resources/application-pgsql.properties) - PostgreSQL 数据库检测**  

```
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
```

**注意**  
有关如何将 PostgreSQL 数据库添加到应用程序环境的详细信息，请参阅 [https://docs.amazonaws.cn/elasticbeanstalk/latest/dg/using-features.managing.db.html](https://docs.amazonaws.cn/elasticbeanstalk/latest/dg/using-features.managing.db.html) 开发人员指南* 中的Amazon Elastic Beanstalk 使用 Elastic Beanstalk 配置数据库*。

`xray` 分支中的 X-Ray 演示页包含一个使用检测的数据源生成跟踪的演示，此跟踪显示有关其生成的 SQL 查询的信息。导航到正在运行的应用程序中的 `/#/xray` 路径，或选择导航栏中的 **Powered by Amazon X-Ray** 查看该演示页。

![\[Amazon X-Ray integration demo page showing game session tracing and SQL query tracing options.\]](http://docs.amazonaws.cn/xray/latest/devguide/images/scorekeep-demo.png)


选择 **Trace SQL queries** 模拟游戏会话并将结果存储在附加的数据库中。然后，选择 “**在 Amazon X-Ray 中查看跟**踪”，查看经过筛选的到达该 API `/api/history` 路线的跟踪列表。

从该列表中选择一个跟踪以查看时间线，包括 SQL 查询。

![\[Timeline view of a trace showing method, response, duration, and age for a GET request.\]](http://docs.amazonaws.cn/xray/latest/devguide/images/scorekeep-trace-sql.png)


# 仪表函数 Amazon Lambda
Amazon Lambda 函数

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

Scorekeep 使用两个 Amazon Lambda 函数。第一个是来自 `lambda` 分支的 Node.js 函数，它为新用户生成随机名称。如果用户在创建会话时未输入名称，则该应用程序将通过 适用于 Java 的 Amazon SDK调用名为 `random-name` 的函数。适用于 Java 的 X-Ray SDK 在子分段中记录有关对 Lambda 的调用的信息，就像使用仪器 Amazon 化的 SDK 客户端进行的任何其他调用一样。

**注意**  
运行 `random-name` Lambda 函数需要在 Elastic Beanstalk 环境外创建其他资源。有关详细信息和说明，请参阅自述文件：[Amazon Lambda 集成](https://github.com/awslabs/eb-java-scorekeep/tree/xray/README.md#aws-lambda-integration)。

第二个函数为 `scorekeep-worker`，它是一个独立于 Scorekeep API 运行的 Python 函数。当游戏结束时，API 将会话 ID 和游戏 ID 写入 SQS 队列。工作线程函数将从队列中读取项目，然后调用 Scorekeep API 来为 Amazon S3 中的存储构建每个游戏会话的完整记录。

Scorekeep 包括用于创建这两个函数的 Amazon CloudFormation 模板和脚本。由于您需要将 X-Ray SDK 与函数代码绑定，因此，这些模板无需任何代码即可创建函数。在部署 Scorekeep 时，`.ebextensions` 文件夹中包含的配置文件将创建一个包含 SDK 的源包并使用 Amazon Command Line Interface更新函数代码和配置。

**Topics**
+ [

## 随机名称
](#scorekeep-lambda-randomname)
+ [

## 工作线程
](#scorekeep-lambda-worker)

## 随机名称


当用户在没有登录或指定用户名的情况下启动游戏会话时，Scorekeep 将调用随机名称函数。当 Lambda 处理对 `random-name` 的调用时，它读取[跟踪标头](xray-concepts.md#xray-concepts-tracingheader)，其中包含 X-Ray SDK for Java 写入的跟踪 ID 和采样决策。

对于每个被采样的请求，Lambda 运行 X-Ray 进程守护程序并编写两个分段。第一个分段记录有关调用函数的 Lambda 调用的信息。但从 Lambda 的角度看，该分段包含与 Scorekeep 记录的子分段相同的信息。第二个分段表示函数所做的工作。

Lambda 通过函数上下文将函数分段传递到 X-Ray SDK。在检测 Lambda 函数时，您不使用 SDK [为传入请求创建分段](xray-sdk-nodejs-middleware.md)。Lambda 将提供分段，并且您将使用 SDK 检测客户端和写入子分段。

![\[演示 Scorekeep 如何调用 Lambda 函数以获取新用户的随机名称的跟踪地图\]](http://docs.amazonaws.cn/xray/latest/devguide/images/scorekeep-servicemap-lambda-node.png)


`random-name` 函数在 Node.js 中实现。它使用 Node.js JavaScript 中的 SDK 通过亚马逊 SNS 发送通知，使用 Node.js 的 X-Ray SDK 来检测 S Amazon DK 客户端。为了写入注释，该函数利用 `AWSXRay.captureFunc` 创建一个自定义子分段，并在经过检测的函数中写入注释。在 Lambda 中，您无法直接将注释写入函数分段，而只能将其写入您创建的子分段。

**Example [https://github.com/awslabs/eb-java-scorekeep/tree/xray/function/index.js](https://github.com/awslabs/eb-java-scorekeep/tree/xray/function/index.js) -- 随机名称 Lambda 函数**  

```
var AWSXRay = require('aws-xray-sdk-core');
var AWS = AWSXRay.captureAWS(require('aws-sdk'));

AWS.config.update({region: process.env.AWS_REGION});
var Chance = require('chance');

var myFunction = function(event, context, callback) {
  var sns = new AWS.SNS();
  var chance = new Chance();
  var userid = event.userid;
  var name = chance.first();

  AWSXRay.captureFunc('annotations', function(subsegment){
    subsegment.addAnnotation('Name', name);
    subsegment.addAnnotation('UserID', event.userid);
  });

  // Notify
  var params = {
    Message: 'Created randon name "' + name + '"" for user "' + userid + '".',
    Subject: 'New user: ' + name,
    TopicArn: process.env.TOPIC_ARN
  };
  sns.publish(params, function(err, data) {
    if (err) {
      console.log(err, err.stack);
      callback(err);
    }
    else {
      console.log(data);
      callback(null, {"name": name});
    }
  });
};

exports.handler = myFunction;
```

在您将示例应用程序部署到 Elastic Beanstalk 时，将自动创建此函数。`xray` 分支包括一个用于创建空白 Lambda 函数的脚本。`.ebextensions`文件夹中的配置文件在部署`npm install`期间使用构建函数包，然后使用 CLI Amazon 更新 Lambda 函数。

## 工作线程


经过检测的工作线程函数在自己的分支 `xray-worker` 中提供，这是因为，除非您先创建工作线程函数和相关资源，否则该函数无法运行。有关说明，请参阅[分支自述文件](https://github.com/awslabs/eb-java-scorekeep/tree/xray-worker/README.md)。

该函数由每 5 分钟一次捆绑的 Amazon Events CloudWatch 事件触发。当该函数运行时，它会从 Scorekeep 管理的 Amazon SQS 队列中拉取项目。每条消息均包含有关已完成游戏的信息。

工作线程将从游戏记录引用的其他表中拉取游戏记录和文档。例如，DynamoDB 中的游戏记录包含在游戏期间执行的移动的列表。该列表不包含动作本身，而是 IDs 存储在单独表中的移动。

会话和状态也将存储为引用。虽然这可阻止游戏表中的条目过大，但需要额外调用来获取有关游戏的所有信息。工作线程会取消引用所有这些条目，并将游戏的完整记录构建为 Amazon S3 中的单一文档。当您要对数据进行分析时，您可以利用 Amazon Athena 直接在 Amazon S3 中对数据运行查询，而无需运行读取密集型数据迁移来拉取 DynamoDB 中的数据。

![\[演示 Scorekeep 工作线程函数如何使用 Amazon SQS、Amazon S3 和 Scorekeep API 的跟踪地图。\]](http://docs.amazonaws.cn/xray/latest/devguide/images/scorekeep-servicemap-lambdaworker-node.png)


工作线程函数已在自身在 Amazon Lambda的配置中启用活动跟踪。与随机命名函数不同，worker 不会收到来自已检测应用程序的请求，因此 Amazon Lambda 不会收到跟踪标头。利用活动跟踪，Lambda 将创建跟踪 ID 并制定采样决策。

适用于 Python 的 X-Ray SDK 只是函数顶部的几行，用于导入软件开发工具包并运行其`patch_all`函数来修补 HTTclients ，它用来调用 Amazon SQS 和 Amazon S3。 Amazon SDK for Python (Boto) 当工作线程调用 Scorekeep API 时，SDK 会将[跟踪标头](xray-concepts.md#xray-concepts-tracingheader)添加到通过 API 跟踪调用的请求中。

**Example [https://github.com/awslabs/eb-java-scorekeep/tree/xray-worker/_lambda/scorekeep-worker/scorekeep-worker.py](https://github.com/awslabs/eb-java-scorekeep/tree/xray-worker/_lambda/scorekeep-worker/scorekeep-worker.py) -- 工作线程 Lambda 函数**  

```
import os
import boto3
import json
import requests
import time
from aws_xray_sdk.core import xray_recorder
from aws_xray_sdk.core import patch_all

patch_all()
queue_url = os.environ['WORKER_QUEUE']

def lambda_handler(event, context):
    # Create SQS client
    sqs = boto3.client('sqs')
    s3client = boto3.client('s3')

    # Receive message from SQS queue
    response = sqs.receive_message(
        QueueUrl=queue_url,
        AttributeNames=[
            'SentTimestamp'
        ],
        MaxNumberOfMessages=1,
        MessageAttributeNames=[
            'All'
        ],
        VisibilityTimeout=0,
        WaitTimeSeconds=0
    )
   ...
```

# 检测启动代码
检测启动代码

**注意**  
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 的 X-Ray 开发工具包自动为传入请求创建分段。只要请求在范围内，您就可以使用检测的客户端和记录子分段，而不会出现问题。但是，如果你尝试在启动代码中使用经过检测的客户端，你会得[SegmentNotFoundException](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/exceptions/SegmentNotFoundException.html)到.

启动代码在 Web 应用程序的标准 request/response 流程之外运行，因此您需要手动创建区段来对其进行检测。Scorekeep 在其 `WebConfig` 文件中显示启动代码的检测。Scorekeep 在启动期间调用 SQL 数据库和 Amazon SNS。

![\[Diagram showing client requests to Scorekeeper-init, which connects to SQL database and SNS.\]](http://docs.amazonaws.cn/xray/latest/devguide/images/scorekeep-servicemap-init.png)


默认 `WebConfig` 类创建通知的 Amazon SNS 订阅。为了提供 X-Ray 开发工具包在使用 Amazon SNS; 客户端时写入的分段，Scorekeep 将在全局记录器上调用 `beginSegment` 和 `endSegment`。

**Example [https://github.com/awslabs/eb-java-scorekeep/tree/xray/src/main/java/scorekeep/WebConfig.java#L49](https://github.com/awslabs/eb-java-scorekeep/tree/xray/src/main/java/scorekeep/WebConfig.java#L49)— 启动代码中装有检测 Amazon 功能的 SDK 客户端**  

```
AWSXRay.beginSegment("Scorekeep-init");
if ( System.getenv("NOTIFICATION_EMAIL") != null ){
  try { Sns.createSubscription(); }
  catch (Exception e ) {
    logger.warn("Failed to create subscription for email "+  System.getenv("NOTIFICATION_EMAIL"));
  }
}
AWSXRay.endSegment();
```

在连接 Amazon RDS 数据库时 Scorekeep 使用的 `RdsWebConfig` 中，配置还为 Hibernate 在启动期间应用数据库架构时使用的 SQL 客户端创建一个分段。

**Example [https://github.com/awslabs/eb-java-scorekeep/tree/xray/src/main/java/scorekeep/RdsWebConfig.java#L83](https://github.com/awslabs/eb-java-scorekeep/tree/xray/src/main/java/scorekeep/RdsWebConfig.java#L83) - 启动代码中的检测过的 SQL 数据库客户端**  

```
@PostConstruct
public void schemaExport() {
  EntityManagerFactoryImpl entityManagerFactoryImpl = (EntityManagerFactoryImpl) localContainerEntityManagerFactoryBean.getNativeEntityManagerFactory();
  SessionFactoryImplementor sessionFactoryImplementor = entityManagerFactoryImpl.getSessionFactory();
  StandardServiceRegistry standardServiceRegistry = sessionFactoryImplementor.getSessionFactoryOptions().getServiceRegistry();
  MetadataSources metadataSources = new MetadataSources(new BootstrapServiceRegistryBuilder().build());
  metadataSources.addAnnotatedClass(GameHistory.class);
  MetadataImplementor metadataImplementor = (MetadataImplementor) metadataSources.buildMetadata(standardServiceRegistry);
  SchemaExport schemaExport = new SchemaExport(standardServiceRegistry, metadataImplementor);

  AWSXRay.beginSegment("Scorekeep-init");
  schemaExport.create(true, true);
  AWSXRay.endSegment();
}
```

`SchemaExport` 自动运行并使用 SQL 客户端。由于对客户端进行检测，Scorekeep 必须覆盖默认实现并提供在调用客户端时开发工具包要使用的分段。

# 检测脚本
检测脚本

**注意**  
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 进程守护程序正在运行时，它会将收到的任何分段中继到 X-Ray，即使它们不是由 X-Ray SDK 生成的。Scorekeep 使用自己的脚本来检测用于在部署过程中编译应用程序的构建方式。

**Example [https://github.com/awslabs/eb-java-scorekeep/tree/xray/bin/build.sh](https://github.com/awslabs/eb-java-scorekeep/tree/xray/bin/build.sh) - 检测过的生成脚本**  

```
SEGMENT=$(python bin/xray_start.py)
gradle build --quiet --stacktrace &> /var/log/gradle.log; GRADLE_RETURN=$?
if (( GRADLE_RETURN != 0 )); then 
  echo "Gradle failed with exit status $GRADLE_RETURN" >&2
  python bin/xray_error.py "$SEGMENT" "$(cat /var/log/gradle.log)"
  exit 1
fi
python bin/xray_success.py "$SEGMENT"
```

[https://github.com/awslabs/eb-java-scorekeep/tree/xray/bin/xray_start.py](https://github.com/awslabs/eb-java-scorekeep/tree/xray/bin/xray_start.py)、[https://github.com/awslabs/eb-java-scorekeep/tree/xray/bin/xray_error.py](https://github.com/awslabs/eb-java-scorekeep/tree/xray/bin/xray_error.py) 和 [https://github.com/awslabs/eb-java-scorekeep/tree/xray/bin/xray_success.py](https://github.com/awslabs/eb-java-scorekeep/tree/xray/bin/xray_success.py) 是简单的 Python 脚本，用于构建分段对象，将它们转换为 JSON 文档并将其通过 UDP 发送到进程守护程序。如果 Gradle 构建失败，您可以通过单击 X-Ray 控制台跟踪地图中的 **scorekeep-build** 节点，找到错误消息。

![\[Diagram showing client connection to Scorekeep-build with average time of 14.6s and 0.07/min.\]](http://docs.amazonaws.cn/xray/latest/devguide/images/scorekeep-servicemap-builderror.png)


![\[Timeline view showing Scorekeep-build process with 14.6 second duration and warning icon.\]](http://docs.amazonaws.cn/xray/latest/devguide/images/scorekeep-timeline-builderror.png)


![\[Error message showing build failure due to missing ElasticBeanstalkPlugin symbol in RdsWebConfig class.\]](http://docs.amazonaws.cn/xray/latest/devguide/images/scorekeep-exception-builderror.png)


# 检测 Web 应用程序客户端
检测 Web 客户端

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

在 [https://github.com/awslabs/eb-java-scorekeep/tree/xray-cognito](https://github.com/awslabs/eb-java-scorekeep/tree/xray-cognito) 分支中，Scorekeep 使用 Amazon Cognito 使用户能够创建账户并使用该账户登录，以便从 Amazon Cognito 用户池中检索各自的用户信息。当用户登录时，Scorekeep 会使用 Amazon Cognito 身份池来获取用于的 Amazon 临时证书。 适用于 JavaScript 的 Amazon SDK

身份池配置为允许已登录用户将跟踪数据写入到 Amazon X-Ray。Web 应用程序使用这些凭证来记录已登录用户的 ID、浏览器路径以及从客户端角度对 Scorekeep API 的调用。

大多数工作在名为 `xray` 的服务类中完成。此服务类提供了方法来生成必需的标识符、创建进行中的分段，对分段进行最终处理以及将分段文档发送给 X-Ray API。

**Example [https://github.com/awslabs/eb-java-scorekeep/tree/xray-cognito/public/app/xray.js](https://github.com/awslabs/eb-java-scorekeep/tree/xray-cognito/public/app/xray.js) - 记录和上传分段**  

```
...
  service.beginSegment = function() {
    var segment = {};
    var traceId = '1-' + service.getHexTime() + '-' + service.getHexId(24);

    var id = service.getHexId(16);
    var startTime = service.getEpochTime();

    segment.trace_id = traceId;
    segment.id = id;
    segment.start_time = startTime;
    segment.name = 'Scorekeep-client';
    segment.in_progress = true;
    segment.user =  sessionStorage['userid'];
    segment.http = {
      request: {
        url: window.location.href
      }
    };

    var documents = [];
    documents[0] = JSON.stringify(segment);
    service.putDocuments(documents);
    return segment;
  }

  service.endSegment = function(segment) {
    var endTime = service.getEpochTime();
    segment.end_time = endTime;
    segment.in_progress = false;
    var documents = [];
    documents[0] = JSON.stringify(segment);
    service.putDocuments(documents);
  }

  service.putDocuments = function(documents) {
    var xray = new AWS.XRay();
    var params = {
      TraceSegmentDocuments: documents
    };
    xray.putTraceSegments(params, function(err, data) {
      if (err) {
        console.log(err, err.stack);
      } else {
        console.log(data);
      }
    })
  }
```

这些方法在 Web 应用程序用来调用 Scorekeep API 的资源服务的标头和 `transformResponse` 函数中调用。要将客户端分段与 API 生成的分段包括在同一跟踪中，Web 应用程序必须在 X-Ray SDK 可读取的[跟踪标头](xray-concepts.md#xray-concepts-tracingheader)（`X-Amzn-Trace-Id`）中包含跟踪 ID 和分段 ID。当检测的 Java 应用程序收到包含此标头的请求时，X-Ray SDK for Java 使用相同的跟踪 ID，并使来自 Web 应用程序客户端的分段成为其分段的父分段。

**Example [https://github.com/awslabs/eb-java-scorekeep/tree/xray-cognito/public/app/services.js](https://github.com/awslabs/eb-java-scorekeep/tree/xray-cognito/public/app/services.js) - 记录 Angular 资源调用分段和编写跟踪标头**  

```
var module = angular.module('scorekeep');
module.factory('SessionService', function($resource, api, XRay) {
  return $resource(api + 'session/:id', { id: '@_id' }, {
    segment: {},
    get: {
      method: 'GET',
      headers: {
        'X-Amzn-Trace-Id': function(config) {
          segment = XRay.beginSegment();
          return XRay.getTraceHeader(segment);
        }
      },
      transformResponse: function(data) {
        XRay.endSegment(segment);
        return angular.fromJson(data);
      },
    },
...
```

生成的跟踪地图包含 Web 应用程序客户端的节点。

![\[\]](http://docs.amazonaws.cn/xray/latest/devguide/images/scorekeep-servicemap-client.png)


包含来自 Web 应用程序的分段的跟踪显示用户在浏览器中可见的 URL（以 `/#/` 开头的路径）。如果没有客户端检测，您只会获取 Web 应用程序调用的 API 资源的 URL（以 `/api/` 开头的路径）。

![\[\]](http://docs.amazonaws.cn/xray/latest/devguide/images/scorekeep-traces-client.png)


# 在工作线程中使用检测的客户端
工作线程

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

当用户在游戏中获胜后，Scorekeep 使用工作线程向 Amazon SNS 发布通知。发布通知的时间会比请求操作其余部分的总时间更长，并且不会影响客户端或用户。因此，以异步方式执行任务是一种改进响应时间的好方法。

但是，在创建线程时，适用于 Java 的 X-Ray 开发工具包不知道哪个分段处于活动状态。结果，当你尝试在线程中使用经过检测的 适用于 Java 的 Amazon SDK 客户端时，它会抛出，从而使线程崩溃。`SegmentNotFoundException`

**Example 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()` 以安全地运行包含对该分段的上下文具有访问权限的工作线程代码。

**Example [https://github.com/awslabs/eb-java-scorekeep/tree/xray/src/main/java/scorekeep/MoveFactory.java#L70](https://github.com/awslabs/eb-java-scorekeep/tree/xray/src/main/java/scorekeep/MoveFactory.java#L70) - 将跟踪上下文传递到工作线程**  

```
import [com.amazonaws.xray.AWSXRay](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRay.html);
import [com.amazonaws.xray.AWSXRayRecorder](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRayRecorder.html);
import [com.amazonaws.xray.entities.Entity](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/entities/Entity.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);
...
      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();
          }
        }
```

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

![\[\]](http://docs.amazonaws.cn/xray/latest/devguide/images/scorekeep-workerthread.png)


有关多线程处理的更多信息，请参阅[在多线程应用程序中的线程之间传递分段上下文](xray-sdk-java-multithreading.md)。