Scorekeep 示例应用程序入门 - AWS X-Ray

Scorekeep 示例应用程序入门

本教程使用 Scorekeep 示例应用程序xray-gettingstarted 分支,使用 AWS CloudFormation 创建和配置资源在 Amazon ECS 上运行示例应用程序和 X-Ray 进程守护程序。该应用程序使用 Spring 框架实施 JSON Web API 和 AWS SDK for Java,以将数据保存到 Amazon DynamoDB。应用程序中的 servlet 筛选器检测该应用程序处理的所有传入请求,而 AWS SDK 客户端上的请求处理程序检测对 DynamoDB 的下游调用。

您可以使用 AWS Management Console 或 AWS CLI 来遵循本教程。

先决条件

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

  1. 如果您使用权限有限的 IAM 用户,请在 IAM 控制台中添加以下用户策略:

    • AWSCloudFormationFullAccess — 用于访问和使用 CloudFormation

    • AmazonS3FullAccess— 用于使用 AWS Management Console 将模板文件上传到 CloudFormation

    • IAMFullAccess — 用于创建 Amazon ECS 和 Amazon EC2 实例角色

    • AmazonEC2FullAccess — 用于创建 Amazon EC2 资源

    • AmazonDynamoDBFullAccess - 用于创建 DynamoDB 表

    • AmazonECS_FullAccess - 用于创建 Amazon ECS 资源

    • AmazonSNSFullAccess - 用于创建 Amazon SNS 主题

    • AWSXrayReadOnlyAccess - 用于查看 X-Ray 控制台中跟踪地图和跟踪的权限

  2. 如需使用 AWS CLI 完整运行整个教程,请安装 CLI 版本 2.7.9 或更高版本,并使用上一步中用户配置 CLI。使用用户配置时,请确保使用该用户配置 AWS CLI。如果未配置区域,则需要将 --region AWS-REGION 附加到每一个 CLI 命令。

  3. 确保已安装 Git,以便克隆示例应用程序存储库。

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

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

使用 CloudFormation 安装 Scorekeep 应用程序

AWS Management Console
使用 AWS Management Console 安装示例应用程序
  1. 打开 CloudFormation 控制台

  2. 选择创建堆栈,然后从下列菜单中选择使用新资源

  3. 指定模板部分,选择上传模板文件

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

  5. 选择下一步以继续。

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

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

  8. 滚动到查看页面底部,选中确认 CloudFormation 可能会使用自定义名称创建 IAM 资源的复选框,然后选择创建堆栈

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

AWS CLI
使用 AWS CLI 安装示例应用程序
  1. 导航到在教程更早时候克隆的 cloudformation 存储库的 xray-scorekeep 文件夹。

    cd xray-scorekeep/cloudformation/
  2. 输入以下 AWS CLI 命令,创建 CloudFormation 堆栈:

    aws cloudformation create-stack --stack-name scorekeep --capabilities "CAPABILITY_NAMED_IAM" --template-body file://cf-resources.yaml
  3. 等待大约 5 分钟,直到 CloudFormation 堆栈状态变为 CREATE_COMPLETE。使用以下 AWS CLI 命令检查状态:

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

生成跟踪数据

示例应用程序包括一个前端 Web 应用程序。使用 Web 应用程序来生成 API 流量并将跟踪数据发送到 X-Ray。首先,使用 AWS Management Console 或 AWS CLI 检索 Web 应用程序 URL:

AWS Management Console
使用 AWS Management Console 查找应用程序 URL
  1. 打开 CloudFormation 控制台

  2. 从列表中选择 scorekeep 堆栈。

  3. scorekeep 堆栈页面上选择输出选项卡,然后选择 LoadBalancerUrl URL 链接打开 Web 应用程序。

AWS CLI
使用 AWS CLI 查找应用程序 URL
  1. 使用以下命令显示 Web 应用程序的 URL:

    aws cloudformation describe-stacks --stack-name scorekeep --query "Stacks[0].Outputs[0].OutputValue"
  2. 复制此 URL 并在浏览器中打开以显示 Scorekeep Web 应用程序。

使用 Web 应用程序生成跟踪数据
  1. 选择 Create 来创建用户和会话。

  2. 键入 game name,将 Rules 设置为 Tic Tac Toe,然后选择 Create 创建一个游戏。

  3. 选择 Play 以启动游戏。

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

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

在 AWS Management Console 中查看跟踪地图

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

X-Ray console
使用 X-Ray 控制台
  1. 打开 X-Ray 控制台的跟踪地图页面。

  2. 控制台将显示该服务的图形表示形式,这是由 X-Ray 利用应用程序发送的跟踪数据生成的。需要时,务必调整跟踪地图的时间段,以确保将会显示自您首次启动该 Web 应用程序以来的所有跟踪。

    X-Ray 跟踪地图时间段

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

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

X-Ray 控制台跟踪地图页面
查找错误原因
  1. 选择名为 SNS 的节点。将会显示该节点的详细信息面板。

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

  3. 跟踪列表中选择跟踪。该跟踪没有方法或 URL,因为它是在启动期间记录的,而不是对传入请求的响应。

    从跟踪列表中选择跟踪
  4. 选择页面底部 Amazon SNS 分段中的错误状态图标,打开 SNS 子分段的异常页面。

    选择错误状态图标以打开 Amazon SNS 子分段的“异常”页面。
  5. X-Ray SDK 会自动捕获由已检测的 AWS SDK 客户端引发的异常并记录堆栈跟踪。

    显示捕获的异常和记录的堆栈跟踪的“异常”选项卡
CloudWatch console
使用 CloudWatch 控制台
  1. 打开 CloudWatch 控制台的 X-Ray 跟踪地图

  2. 控制台将显示该服务的图形表示形式,这是由 X-Ray 利用应用程序发送的跟踪数据生成的。需要时,务必调整跟踪地图的时间段,以确保将会显示自您首次启动该 Web 应用程序以来的所有跟踪。

    CloudWatch 跟踪地图时间段

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

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

X-Ray 控制台跟踪地图页面
查找错误原因
  1. 选择名为 SNS 的节点。地图下方显示 SNS 节点详细信息面板。

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

  3. 添加页面底部,从跟踪列表中选择跟踪。该跟踪没有方法或 URL,因为它是在启动期间记录的,而不是对传入请求的响应。

    从跟踪列表中选择跟踪
  4. 在分段时间线底部选择 Amazon SNS 子分段,然后选择该 SNS 子分段的异常选项卡以查看异常详细信息。

    查看 Amazon SNS 子分段的“异常”选项卡

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

配置 Amazon SNS 通知

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

AWS Management Console
如何使用 AWS Management Console 来配置 Amazon SNS 通知
  1. 打开 CloudFormation 控制台

  2. 在列表中选择 scorekeep 堆栈名称旁边的单选按钮,然后选择更新

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

  4. 在列表中找到电子邮件参数,将默认值替换为有效的电子邮件地址。

    更新电子邮件配置
  5. 滚动到页面底部并选择下一步

  6. 滚动到查看页面底部,选中确认 CloudFormation 可能会使用自定义名称创建 IAM 资源的复选框,然后选择更新堆栈

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

AWS CLI
如何使用 AWS CLI 来配置 Amazon SNS 通知
  1. 导航到之前创建的 xray-scorekeep/cloudformation/ 文件夹,然后在文本编辑器打开 cf-resources.yaml 文件。

  2. 电子邮件参数中找到 Default 值,将其从 UPDATE_ME 更改为有效的电子邮件地址。

    Parameters: Email: Type: String Default: UPDATE_ME # <- change to a valid abc@def.xyz email address
  3. cloudformation 文件夹中,使用以下 AWS CLI 命令更新 CloudFormation 堆栈:

    aws cloudformation update-stack --stack-name scorekeep --capabilities "CAPABILITY_NAMED_IAM" --template-body file://cf-resources.yaml
  4. 等待大约几分钟,直到 CloudFormation 堆栈状态变为 UPDATE_COMPLETE。使用以下 AWS 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 模板部署应用程序时,会创建在 ECS 上运行 Scorekeep 所需的 DynamoDB 表、Amazon ECS 集群和其他服务。ECS 的一项任务定义文件通过 CloudFormation 创建。此文件定义 ECS 集群中每项任务使用的容器映像。这些映像从官方 X-Ray 公共 ECR 中获取。Scorekeep API 容器映像具有兼容 Gradle 的 API。Scorekeeep 前端容器的容器映像充当使用 nginx 代理服务器的前端。此服务器会将传送到以 /api 开头的路径的请求路由到 API。

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

例 src/main/java/scorekeep/WebConfig.java - Servlet 筛选器
import javax.servlet.Filter; import com.amazonaws.xray.javax.servlet.AWSXRayServletFilter; ... @Configuration public class WebConfig { @Bean public Filter TracingFilter() { return new AWSXRayServletFilter("Scorekeep"); } ...

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

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

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

例 使用 Docker 通过 Gradle Docker 映像进行构建
docker run --rm -v /PATH/TO/SCOREKEEP_REPO/home/gradle/project -w /home/gradle/project gradle:4.3 gradle build
例 Dockerfile ENTRYPOINT
ENTRYPOINT [ "sh", "-c", "java -Dserver.port=5000 -jar scorekeep-api-1.0.0.jar" ]

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

例 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") } }

只需拥有核心、AWS SDK 和 AWS SDK Instrumentor 子模块就可以自动检测 AWS SDK 进行的所有下游调用。

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

例 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 类中的一个静态数据块,该数据块使用插件和示例规则配置全局记录器。

例 src/main/java/scorekeep/WebConfig.java - Recorder
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 记录传入请求分段的速率。

例 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 调用。有关更多信息,请参阅 AWS X-Ray 应用程序示例

可选:最低权限策略

Scorekeeep ECS 容器使用 AmazonSNSFullAccessAmazonDynamoDBFullAccess 等完整访问策略来访问资源。对于生产应用程序而言,使用完整访问策略并不是最佳做法。以下示例更新 DynamoDB IAM 策略以提升应用程序的安全性。要了解有关 IAM 策略的安全性最佳实践的更多信息,请参阅适用于 AWS X-Ray 的身份和访问管理

例 cf-resources.yaml 模板 ECSTaskRole 定义
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 控制台

  2. 从左侧导航栏中选择

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

  4. 概述选项卡下,选择其他信息展开此部分,查看 Amazon 资源名称(ARN)。复制该值。

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

    { "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:<AWS_REGION>:<AWS_ACCOUNT_ID>:table/scorekeep-*" } ] }

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

更改 IAM 策略
  1. 从 IAM 控制台打开 Scorekeep 任务角色 (scorekeepRole)

  2. 选择 AmazonDynamoDBFullAccess 策略旁边的复选框,然后选择删除以删除此策略。

  3. 选择添加权限,然后选择附加策略,最后选择创建策略

  4. 选择 JSON 选项卡,然后粘贴上面创建的策略。

  5. 在页面底部,选择下一步:标签

  6. 在页面底部,选择下一步:查看

  7. 名称中,为策略分配一个名称。

  8. 在页面底部,选择创建策略

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

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

删除自定义 IAM 策略
  1. 打开 IAM 控制台

  2. 从左侧导航菜单中,选择策略

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

  4. 选择操作下拉列表,然后选择删除

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

清理

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

注意

如果您使用本教程上一节,创建并附加了自定义策略,则必须先从 scorekeepRole 删除策略,再删除 CloudFormation 堆栈。

AWS Management Console
使用 AWS Management Console 删除示例应用程序
  1. 打开 CloudFormation 控制台

  2. 在列表中选择 scorekeep 堆栈名称旁边的单选按钮,然后选择删除

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

AWS CLI
使用 AWS CLI 删除示例应用程序
  1. 输入以下 AWS CLI 命令,删除 CloudFormation 堆栈:

    aws cloudformation delete-stack --stack-name scorekeep
  2. 等待大约 5 分钟,直到 CloudFormation 堆栈不再存在。使用以下 AWS CLI 命令检查状态:

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

后续步骤

要了解有关 X-Ray 的更多信息,请参阅下一章AWS X-Ray 概念

要检测您自己的应用程序,请了解有关 X-Ray SDK for Java 或其他 X-Ray SDK 的更多信息:

请参阅 AWS X-Ray 进程守护程序,了解如何在本地或 AWS 上运行 X-Ray 进程守护程序。

要更好地了解 GitHub 上的示例应用程序,请参阅 eb-java-scorekeep