在 AWS Lambda 中检测 Java 代码 - AWS Lambda

在 AWS Lambda 中检测 Java 代码

Lambda 与 AWS X-Ray 集成,以帮助您跟踪、调试和优化 Lambda 应用程序。您可以在某个请求遍历应用程序中的资源(其中可能包括 Lambda 函数和其他 AWS 服务)时,使用 X-Ray 跟踪该请求。

要将跟踪数据发送到 X-Ray,您可以使用以下两个软件开发工具包 (SDK) 库之一:

每个开发工具包均提供了将遥测数据发送到 X-Ray 服务的方法。然后,您可以使用 X-Ray 查看、筛选和获得对应用程序性能指标的洞察,从而发现问题和优化机会。

重要

X-Ray 和 Powertools for AWS Lambda SDK 是 AWS 提供的紧密集成的分析解决方案的一部分。ADOT Lambda Layers 是全行业通用的跟踪分析标准的一部分,该标准通常会收集更多数据,但可能不适用于所有使用案例。您可以使用任一解决方案在 X-Ray 中实现端到端跟踪。要了解有关如何在两者之间进行选择的更多信息,请参阅在 AWS Distro for Open Telemetry 和 X-Ray 开发工具包之间进行选择

将 Powertools for AWS Lambda(Java)和 AWS SAM 用于跟踪

请按照以下步骤使用 AWS SAM,通过集成的 Powertools for AWS Lambda(Java)模块来下载、构建和部署示例 Hello World Java 应用程序。此应用程序实现了基本的 API 后端,并使用 Powertools 发送日志、指标和跟踪。它由 Amazon API Gateway 端点和 Lambda 函数组成。在向 API Gateway 端点发送 GET 请求时,Lambda 函数会使用嵌入式指标格式向 CloudWatch 调用、发送日志和指标,并向 AWS X-Ray 发送跟踪。该函数将返回一条 hello world 消息。

先决条件

要完成本节中的步骤,您必须满足以下条件:

部署示例 AWS SAM 应用程序
  1. 使用 Hello World Java 模板初始化该应用程序。

    sam init --app-template hello-world-powertools-java --name sam-app --package-type Zip --runtime java11 --no-tracing
  2. 构建应用程序。

    cd sam-app && sam build
  3. 部署应用程序。

    sam deploy --guided
  4. 按照屏幕上的提示操作。要在交互式体验中接受提供的默认选项,请按 Enter

    注意

    对于 HelloWorldFunction 可能没有定义授权,确定执行此操作吗?,确保输入 y

  5. 获取已部署应用程序的 URL:

    aws cloudformation describe-stacks --stack-name sam-app --query 'Stacks[0].Outputs[?OutputKey==`HelloWorldApi`].OutputValue' --output text
  6. 调用 API 端点:

    curl -X GET <URL_FROM_PREVIOUS_STEP>

    如果成功,您将会看到如下响应:

    {"message":"hello world"}
  7. 要获取该函数的跟踪信息,请运行 sam traces

    sam traces

    该跟踪输出类似于以下示例:

    New XRay Service Graph Start time: 2023-02-03 14:31:48+01:00 End time: 2023-02-03 14:31:48+01:00 Reference Id: 0 - (Root) AWS::Lambda - sam-app-HelloWorldFunction-y9Iu1FLJJBGD - Edges: [] Summary_statistics: - total requests: 1 - ok count(2XX): 1 - error count(4XX): 0 - fault count(5XX): 0 - total response time: 5.587 Reference Id: 1 - client - sam-app-HelloWorldFunction-y9Iu1FLJJBGD - Edges: [0] Summary_statistics: - total requests: 0 - ok count(2XX): 0 - error count(4XX): 0 - fault count(5XX): 0 - total response time: 0 XRay Event [revision 3] at (2023-02-03T14:31:48.500000) with id (1-63dd0cc4-3c869dec72a586875da39777) and duration (5.603s) - 5.587s - sam-app-HelloWorldFunction-y9Iu1FLJJBGD [HTTP: 200] - 4.053s - sam-app-HelloWorldFunction-y9Iu1FLJJBGD - 1.181s - Initialization - 4.037s - Invocation - 1.981s - ## handleRequest - 1.840s - ## getPageContents - 0.000s - Overhead
  8. 这是一个可以通过互联网访问的公有 API 端点。我们建议您在测试后删除该端点。

    sam delete

将 Powertools for AWS Lambda(Java)和 AWS CDK 用于跟踪

请按照以下步骤使用 AWS CDK,通过集成的 Powertools for AWS Lambda(Java)模块来下载、构建和部署示例 Hello World Java 应用程序。此应用程序实现了基本的 API 后端,并使用 Powertools 发送日志、指标和跟踪。它由 Amazon API Gateway 端点和 Lambda 函数组成。在向 API Gateway 端点发送 GET 请求时,Lambda 函数会使用嵌入式指标格式向 CloudWatch 调用、发送日志和指标,并向 AWS X-Ray 发送跟踪。该函数将返回一条 hello world 消息。

先决条件

要完成本节中的步骤,您必须满足以下条件:

部署示例 AWS CDK 应用程序
  1. 为您的新应用程序创建一个项目目录。

    mkdir hello-world cd hello-world
  2. 初始化该应用程序。

    cdk init app --language java
  3. 使用以下命令创建 Maven 项目:

    mkdir app cd app mvn archetype:generate -DgroupId=helloworld -DartifactId=Function -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
  4. 打开 hello-world\app\Function 目录中的 pom.xml,并将现有代码替换为以下代码,其中包括 Powertools 的依赖项和 Maven 插件。

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>helloworld</groupId> <artifactId>Function</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> <name>Function</name> <url>http://maven.apache.org</url> <properties> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> <log4j.version>2.17.2</log4j.version> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>software.amazon.lambda</groupId> <artifactId>powertools-tracing</artifactId> <version>1.3.0</version> </dependency> <dependency> <groupId>software.amazon.lambda</groupId> <artifactId>powertools-metrics</artifactId> <version>1.3.0</version> </dependency> <dependency> <groupId>software.amazon.lambda</groupId> <artifactId>powertools-logging</artifactId> <version>1.3.0</version> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-core</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-events</artifactId> <version>3.11.1</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>aspectj-maven-plugin</artifactId> <version>1.14.0</version> <configuration> <source>${maven.compiler.source}</source> <target>${maven.compiler.target}</target> <complianceLevel>${maven.compiler.target}</complianceLevel> <aspectLibraries> <aspectLibrary> <groupId>software.amazon.lambda</groupId> <artifactId>powertools-tracing</artifactId> </aspectLibrary> <aspectLibrary> <groupId>software.amazon.lambda</groupId> <artifactId>powertools-metrics</artifactId> </aspectLibrary> <aspectLibrary> <groupId>software.amazon.lambda</groupId> <artifactId>powertools-logging</artifactId> </aspectLibrary> </aspectLibraries> </configuration> <executions> <execution> <goals> <goal>compile</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.4.1</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <transformer implementation="com.github.edwgiz.maven_shade_plugin.log4j2_cache_transformer.PluginsCacheFileTransformer"> </transformer> </transformers> <createDependencyReducedPom>false</createDependencyReducedPom> <finalName>function</finalName> </configuration> </execution> </executions> <dependencies> <dependency> <groupId>com.github.edwgiz</groupId> <artifactId>maven-shade-plugin.log4j2-cachefile-transformer</artifactId> <version>2.15</version> </dependency> </dependencies> </plugin> </plugins> </build> </project>
  5. 创建 hello-world\app\src\main\resource 目录并为日志配置创建 log4j.xml

    mkdir -p src/main/resource cd src/main/resource touch log4j.xml
  6. 打开 log4j.xml 并添加以下代码。

    <?xml version="1.0" encoding="UTF-8"?> <Configuration> <Appenders> <Console name="JsonAppender" target="SYSTEM_OUT"> <JsonTemplateLayout eventTemplateUri="classpath:LambdaJsonLayout.json" /> </Console> </Appenders> <Loggers> <Logger name="JsonLogger" level="INFO" additivity="false"> <AppenderRef ref="JsonAppender"/> </Logger> <Root level="info"> <AppenderRef ref="JsonAppender"/> </Root> </Loggers> </Configuration>
  7. 打开 hello-world\app\Function\src\main\java\helloworld 目录中的 App.java,并将现有代码替换为以下代码。这是适用于 Lambda 函数的代码。

    package helloworld; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.URL; import java.util.HashMap; import java.util.Map; import java.util.stream.Collectors; import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.RequestHandler; import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent; import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import software.amazon.lambda.powertools.logging.Logging; import software.amazon.lambda.powertools.metrics.Metrics; import software.amazon.lambda.powertools.tracing.CaptureMode; import software.amazon.lambda.powertools.tracing.Tracing; import static software.amazon.lambda.powertools.tracing.CaptureMode.*; /** * Handler for requests to Lambda function. */ public class App implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> { Logger log = LogManager.getLogger(App.class); @Logging(logEvent = true) @Tracing(captureMode = DISABLED) @Metrics(captureColdStart = true) public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEvent input, final Context context) { Map<String, String> headers = new HashMap<>(); headers.put("Content-Type", "application/json"); headers.put("X-Custom-Header", "application/json"); APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent() .withHeaders(headers); try { final String pageContents = this.getPageContents("https://checkip.amazonaws.com"); String output = String.format("{ \"message\": \"hello world\", \"location\": \"%s\" }", pageContents); return response .withStatusCode(200) .withBody(output); } catch (IOException e) { return response .withBody("{}") .withStatusCode(500); } } @Tracing(namespace = "getPageContents") private String getPageContents(String address) throws IOException { log.info("Retrieving {}", address); URL url = new URL(address); try (BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()))) { return br.lines().collect(Collectors.joining(System.lineSeparator())); } } }
  8. 打开 hello-world\src\main\java\com\myorg 目录中的 HelloWorldStack.java,并将现有代码替换为以下代码。此代码将使用 Lambda 构造函数ApiGatewayv2 构造函数创建 REST API 和 Lambda 函数。

    package com.myorg; import software.amazon.awscdk.*; import software.amazon.awscdk.services.apigatewayv2.alpha.*; import software.amazon.awscdk.services.apigatewayv2.integrations.alpha.HttpLambdaIntegration; import software.amazon.awscdk.services.apigatewayv2.integrations.alpha.HttpLambdaIntegrationProps; import software.amazon.awscdk.services.lambda.Code; import software.amazon.awscdk.services.lambda.Function; import software.amazon.awscdk.services.lambda.FunctionProps; import software.amazon.awscdk.services.lambda.Runtime; import software.amazon.awscdk.services.lambda.Tracing; import software.amazon.awscdk.services.logs.RetentionDays; import software.amazon.awscdk.services.s3.assets.AssetOptions; import software.constructs.Construct; import java.util.Arrays; import java.util.List; import static java.util.Collections.singletonList; import static software.amazon.awscdk.BundlingOutput.ARCHIVED; public class HelloWorldStack extends Stack { public HelloWorldStack(final Construct scope, final String id) { this(scope, id, null); } public HelloWorldStack(final Construct scope, final String id, final StackProps props) { super(scope, id, props); List<String> functionPackagingInstructions = Arrays.asList( "/bin/sh", "-c", "cd Function " + "&& mvn clean install " + "&& cp /asset-input/Function/target/function.jar /asset-output/" ); BundlingOptions.Builder builderOptions = BundlingOptions.builder() .command(functionPackagingInstructions) .image(Runtime.JAVA_11.getBundlingImage()) .volumes(singletonList( // Mount local .m2 repo to avoid download all the dependencies again inside the container DockerVolume.builder() .hostPath(System.getProperty("user.home") + "/.m2/") .containerPath("/root/.m2/") .build() )) .user("root") .outputType(ARCHIVED); Function function = new Function(this, "Function", FunctionProps.builder() .runtime(Runtime.JAVA_11) .code(Code.fromAsset("app", AssetOptions.builder() .bundling(builderOptions .command(functionPackagingInstructions) .build()) .build())) .handler("helloworld.App::handleRequest") .memorySize(1024) .tracing(Tracing.ACTIVE) .timeout(Duration.seconds(10)) .logRetention(RetentionDays.ONE_WEEK) .build()); HttpApi httpApi = new HttpApi(this, "sample-api", HttpApiProps.builder() .apiName("sample-api") .build()); httpApi.addRoutes(AddRoutesOptions.builder() .path("/") .methods(singletonList(HttpMethod.GET)) .integration(new HttpLambdaIntegration("function", function, HttpLambdaIntegrationProps.builder() .payloadFormatVersion(PayloadFormatVersion.VERSION_2_0) .build())) .build()); new CfnOutput(this, "HttpApi", CfnOutputProps.builder() .description("Url for Http Api") .value(httpApi.getApiEndpoint()) .build()); } }
  9. 打开 hello-world 目录中的 pom.xml,并将现有代码替换为以下代码。

    <?xml version="1.0" encoding="UTF-8"?> <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <groupId>com.myorg</groupId> <artifactId>hello-world</artifactId> <version>0.1</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <cdk.version>2.70.0</cdk.version> <constructs.version>[10.0.0,11.0.0)</constructs.version> <junit.version>5.7.1</junit.version> </properties> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>3.0.0</version> <configuration> <mainClass>com.myorg.HelloWorldApp</mainClass> </configuration> </plugin> </plugins> </build> <dependencies> <!-- AWS Cloud Development Kit --> <dependency> <groupId>software.amazon.awscdk</groupId> <artifactId>aws-cdk-lib</artifactId> <version>${cdk.version}</version> </dependency> <dependency> <groupId>software.constructs</groupId> <artifactId>constructs</artifactId> <version>${constructs.version}</version> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>software.amazon.awscdk</groupId> <artifactId>apigatewayv2-alpha</artifactId> <version>${cdk.version}-alpha.0</version> </dependency> <dependency> <groupId>software.amazon.awscdk</groupId> <artifactId>apigatewayv2-integrations-alpha</artifactId> <version>${cdk.version}-alpha.0</version> </dependency> </dependencies> </project>
  10. 确保您位于 hello-world 目录中然后部署应用程序。

    cdk deploy
  11. 获取已部署应用程序的 URL:

    aws cloudformation describe-stacks --stack-name HelloWorldStack --query 'Stacks[0].Outputs[?OutputKey==`HttpApi`].OutputValue' --output text
  12. 调用 API 端点:

    curl -X GET <URL_FROM_PREVIOUS_STEP>

    如果成功,您将会看到如下响应:

    {"message":"hello world"}
  13. 要获取该函数的跟踪信息,请运行 sam traces

    sam traces

    该跟踪输出类似于以下示例:

    New XRay Service Graph Start time: 2023-02-03 14:59:50+00:00 End time: 2023-02-03 14:59:50+00:00 Reference Id: 0 - (Root) AWS::Lambda - sam-app-HelloWorldFunction-YBg8yfYtOc9j - Edges: [1] Summary_statistics: - total requests: 1 - ok count(2XX): 1 - error count(4XX): 0 - fault count(5XX): 0 - total response time: 0.924 Reference Id: 1 - AWS::Lambda::Function - sam-app-HelloWorldFunction-YBg8yfYtOc9j - Edges: [] Summary_statistics: - total requests: 1 - ok count(2XX): 1 - error count(4XX): 0 - fault count(5XX): 0 - total response time: 0.016 Reference Id: 2 - client - sam-app-HelloWorldFunction-YBg8yfYtOc9j - Edges: [0] Summary_statistics: - total requests: 0 - ok count(2XX): 0 - error count(4XX): 0 - fault count(5XX): 0 - total response time: 0 XRay Event [revision 1] at (2023-02-03T14:59:50.204000) with id (1-63dd2166-434a12c22e1307ff2114f299) and duration (0.924s) - 0.924s - sam-app-HelloWorldFunction-YBg8yfYtOc9j [HTTP: 200] - 0.016s - sam-app-HelloWorldFunction-YBg8yfYtOc9j - 0.739s - Initialization - 0.016s - Invocation - 0.013s - ## lambda_handler - 0.000s - ## app.hello - 0.000s - Overhead
  14. 这是一个可以通过互联网访问的公有 API 端点。我们建议您在测试后删除该端点。

    cdk destroy

使用 ADOT 分析您的 Java 函数

ADOT 提供完全托管式 Lambda ,这些层使用 OTel SDK,将收集遥测数据所需的一切内容打包起来。通过使用此层,您可以在不必修改任何函数代码的情况下,对您的 Lambda 函数进行分析。您还可以将您的层配置为对 OTel 进行自定义初始化。有关更多信息,请参阅 ADOT 文档中的适用于 Lambda 上的 ADOT 收集器的自定义配置

对于 Java 运行时,您可以在两个层之间选择使用:

使用 X-Ray SDK 分析您的 Java 函数

要记录关于您的函数对应用程序中的其他资源和服务进行调用的数据,您可以将适用于 Java 的 X-Ray SDK 添加到您的构建配置中。以下示例显示了一种 Gradle 构建配置,其中包括激活 AWS SDK for Java 2.x 客户端自动分析的库。

build.gradle – 跟踪依赖项
dependencies { implementation platform('software.amazon.awssdk:bom:2.16.1') implementation platform('com.amazonaws:aws-xray-recorder-sdk-bom:2.11.0') ... implementation 'com.amazonaws:aws-xray-recorder-sdk-core' implementation 'com.amazonaws:aws-xray-recorder-sdk-aws-sdk' implementation 'com.amazonaws:aws-xray-recorder-sdk-aws-sdk-v2-instrumentor' ... }

在添加正确的依赖项并进行必要的代码更改后,请通过 Lambda 控制台或 API 激活函数配置中的跟踪。

使用 Lambda 控制台激活跟踪

要使用控制台切换 Lambda 函数的活动跟踪,请按照以下步骤操作:

打开活跃跟踪
  1. 打开 Lamba 控制台的 Functions(函数)页面。

  2. 选择函数。

  3. 选择 Configuration(配置),然后选择 Monitoring and operations tools(监控和操作工具)。

  4. 选择编辑

  5. X-Ray 下方,开启 Active tracing(活动跟踪)。

  6. 选择保存

使用 Lambda API 激活跟踪

借助 AWS CLI 或 AWS SDK 在 Lambda 函数上配置跟踪,请使用以下 API 操作:

以下示例 AWS CLI 命令对名为 my-function 的函数启用活跃跟踪。

aws lambda update-function-configuration --function-name my-function \ --tracing-config Mode=Active

跟踪模式是发布函数版本时版本特定配置的一部分。您无法更改已发布版本上的跟踪模式。

使用 AWS CloudFormation 激活跟踪

要对 AWS CloudFormation 模板中的 AWS::Lambda::Function 资源激活跟踪,请使用 TracingConfig 属性。

function-inline.yml – 跟踪配置
Resources: function: Type: AWS::Lambda::Function Properties: TracingConfig: Mode: Active ...

对于 AWS Serverless Application Model (AWS SAM) AWS::Serverless::Function 资源,请使用 Tracing 属性。

template.yml – 跟踪配置
Resources: function: Type: AWS::Serverless::Function Properties: Tracing: Active ...

解释 X-Ray 跟踪

您的函数需要权限才能将跟踪数据上载到 X-Ray。在 Lambda 控制台中激活跟踪后,Lambda 会将所需权限添加到函数的执行角色。如果没有,请将 AWSXRayDaemonWriteAccess 策略添加到执行角色。

在配置活跃跟踪后,您可以通过应用程序观察特定请求。X-Ray 服务图将显示有关应用程序及其所有组件的信息。以下示例显示了具有两个函数的应用程序。主函数处理事件,有时会返回错误。位于顶部的第二个函数将处理第一个函数的日志组中显示的错误,并使用 AWS SDK 调用 X-Ray、Amazon Simple Storage Service (Amazon S3) 和 Amazon CloudWatch Logs。

一幅显示 X-Ray 中两个独立应用程序及其各自服务地图的图

X-Ray 无法跟踪对应用程序的所有请求。X-Ray 将应用采样算法确保跟踪有效,同时仍会提供所有请求的一个代表性样本。采样率是每秒 1 个请求和 5% 的其他请求。您无法为函数配置此 X-Ray 采样率。

在 X-Ray 中,跟踪记录有关由一个或多个服务处理的请求的信息。Lambda 会每个跟踪记录 2 个分段,这些分段将在服务图上创建两个节点。下图突出显示了这两个节点:

具有单个函数的 X-Ray 服务地图。

位于左侧的第一个节点表示接收调用请求的 Lambda 服务。第二个节点表示特定的 Lambda 函数。以下示例显示了一个包含这 2 个分段的跟踪。两者都命名为 my-function,但其中一个函数具有 AWS::Lambda 源,另一个则具有 AWS::Lambda::Function 源。如果 AWS::Lambda 分段显示错误,则表示 Lambda 服务存在问题。如果 AWS::Lambda::Function 分段显示错误,则说明函数存在问题。

一个 X-Ray 跟踪,它将显示特定 Lambda 调用的每个子分段的延迟。

此示例将展开 AWS::Lambda::Function 分段,以显示其三个子分段。

注意

AWS 目前正在实施对 Lambda 服务的更改。由于这些更改,您可能会看到 AWS 账户 中不同 Lambda 函数发出的系统日志消息和跟踪分段的结构和内容之间存在细微差异。

此处显示的示例跟踪说明了旧样式函数分段。以下段落介绍了新旧样式分段之间的差异。

这些更改将在未来几周内实施,除中国和 GovCloud 区域外,所有 AWS 区域 的函数都将过渡到使用新格式的日志消息和跟踪分段。

旧样式函数分段包含以下子分段:

  • 初始化 – 表示加载函数和运行初始化代码所花费的时间。此子分段仅对由您的函数的每个实例处理的第一个事件显示。

  • 调用 – 表示执行处理程序代码花费的时间。

  • 开销 – 表示 Lambda 运行时为准备处理下一个事件而花费的时间。

新样式函数分段不包含 Invocation 子分段。而是将客户子分段直接附加到函数分段。有关新旧样式函数分段结构的更多信息,请参阅 了解 X-Ray 跟踪

注意

Lambda SnapStart 函数还包括一个 Restore 子分段。Restore 子分段会显示 Lambda 恢复快照、加载运行时系统(JVM)和运行任何 afterRestore 运行时系统挂钩所花费的时间。恢复快照的过程可能包含在 MicroVM 之外的活动上花费的时间。该时间在 Restore 子分段中报告。您无需为在 microVM 之外还原快照所花费的时间付费。

您还可以分析 HTTP 客户端、记录 SQL 查询以及使用注释和元数据创建自定义子段。有关更多信息,请参阅 AWS X-Ray 开发人员指南中的 AWS X-Ray SDK for Java

定价

作为 AWS 免费套餐的组成部分,您可以每月免费使用 X-Ray 跟踪,但不能超过一定限制。超出该阈值后,X-Ray 会对跟踪存储和检索进行收费。有关更多信息,请参阅 AWS X-Ray 定价

在层中存储运行时依赖项 (X-Ray SDK)

如果您使用 X-Ray 开发工具包来分析AWS开发工具包客户端和您的函数代码,则您的部署程序包可能会变得相当大。为了避免每次更新函数代码时上载运行时依赖项,请将 X-Ray SDK 打包到 Lambda 层中。

以下示例显示了存储适用于 Java 的 AWS SDK for Java 和 X-Ray SDK 的 AWS::Serverless::LayerVersion 资源。

template.yml – 依赖项层
Resources: function: Type: AWS::Serverless::Function Properties: CodeUri: build/distributions/blank-java.zip Tracing: Active Layers: - !Ref libs ... libs: Type: AWS::Serverless::LayerVersion Properties: LayerName: blank-java-lib Description: Dependencies for the blank-java sample app. ContentUri: build/blank-java-lib.zip CompatibleRuntimes: - java21

使用此配置,仅在更改运行时依赖项时您才会更新库层。由于函数部署软件包仅包含您的代码,因此可以帮助缩短上传时间。

为依赖项创建层要求更改构建配置才能在部署之前生成层存档。有关工作示例,请参阅 GitHub 上的 java-basic 示例应用程序。

示例应用程序中的 X-Ray 跟踪 (X-Ray SDK)

本指南的 GitHub 存储库包括演示如何使用 X-Ray 跟踪的示例应用程序。每个示例应用程序都包含用于轻松部署和清理的脚本、一个 AWS SAM 模板和支持资源。

Java 中的 Lambda 应用程序示例
  • java17-examples:这是一种 Java 函数,演示如何使用 Java 记录来表示输入事件数据对象。

  • java-basic – 具有单元测试和变量日志记录配置的最小 Java 函数的集合。

  • java-events – Java 函数的集合,其中包含用于处理来自 Amazon API Gateway、Amazon SQS 和 Amazon Kinesis 等各种服务的事件的框架代码。这些函数使用最新版本的 aws-lambda-events 库(3.0.0 及更新版本)。这些示例不需要 AWS 开发工具包作为依赖项。

  • s3-java – 此 Java 函数可处理来自 Amazon S3 的通知事件,并使用 Java 类库(JCL)从上传的图像文件创建缩略图。

  • 自定义序列化 –如何使用 fastJson、Gson、Moshi 和 jackson-jr 等常用库实现自定义序列化的示例。

  • 使用 API Gateway 调用 Lambda 函数 – Java 函数,用于扫描包含员工信息的 Amazon DynamoDB 表。然后,该函数使用 Amazon Simple Notification Service 向员工发送短信,祝贺他们工作周年纪念日快乐。此示例使用 API Gateway 调用函数。

所有示例应用程序都为 Lambda 功能启用了活动跟踪。例如,s3-java 应用程序显示 AWS SDK for Java 2.x 客户端的自动分析、用于测试的段管理、自定义子段以及使用 Lambda 层存储运行时依赖项。