Java 中的 AWS Lambda 部署程序包 - AWS Lambda

Java 中的 AWS Lambda 部署程序包

部署程序包是包含已编译的函数代码和依赖项的 ZIP 存档。您可以将程序包直接上传到 Lambda,也可以使用 Amazon S3 存储桶、然后再将其上传到 Lambda。如果部署包大于 50 MB,则必须使用 Amazon S3。

AWS Lambda 提供以下适用于 Java 函数的库:

这些库可通过 Maven 中央存储库获得。将它们添加到您的构建定义中,如下所示。

Gradle
dependencies { implementation 'com.amazonaws:aws-lambda-java-core:1.2.1' implementation 'com.amazonaws:aws-lambda-java-events:2.2.9' runtimeOnly 'com.amazonaws:aws-lambda-java-log4j2:1.2.0' }
Maven
<dependencies> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-core</artifactId> <version>1.2.1</version> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-events</artifactId> <version>2.2.9</version> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-log4j2</artifactId> <version>1.2.0</version> </dependency> </dependencies>

要创建部署程序包,请将函数代码和依赖项编译成单个 ZIP 或 Java 存档 (JAR) 文件。对于 Gradle,请使用 Zip 构建类型。对于 Maven,请使用 Maven Shade 插件

注意

为了减小部署程序包的大小,请将函数的依赖项打包到层中。层可让您独立管理依赖项,可以供多个函数使用,并且可以与其他账户共享。有关详细信息,请参阅AWS Lambda 层

您可以使用 Lambda 控制台、Lambda API 或 AWS SAM 上传部署程序包。

使用 Lambda 控制台上传部署程序包

  1. 打开 Lambda 控制台 函数页面

  2. 选择函数。

  3. Function code (函数包) 下,选择 Upload (上传)

  4. 构建部署程序包。

  5. 选择保存

使用 Gradle 构建部署程序包

使用 Zip 构建类型以创建包含函数代码和依赖项的部署程序包。

例 build.gradle – 构建任务

task buildZip(type: Zip) { from compileJava from processResources into('lib') { from configurations.runtimeClasspath } }

此构建配置在 build/distributions 文件夹中生成部署程序包。compileJava 任务编译函数的类。这些 processResources 任务将构建的类路径中的库复制到名为 lib 的文件夹中。

例 build.gradle – 依赖项

dependencies { implementation platform('software.amazon.awssdk:bom:2.10.73') implementation 'software.amazon.awssdk:lambda' implementation 'com.amazonaws:aws-lambda-java-core:1.2.1' implementation 'com.amazonaws:aws-lambda-java-events:2.2.9' implementation 'com.google.code.gson:gson:2.8.6' implementation 'org.apache.logging.log4j:log4j-api:2.13.0' implementation 'org.apache.logging.log4j:log4j-core:2.13.0' runtimeOnly 'org.apache.logging.log4j:log4j-slf4j18-impl:2.13.0' runtimeOnly 'com.amazonaws:aws-lambda-java-log4j2:1.2.0' testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.6.0' }

Lambda 按 Unicode 字母顺序加载 JAR 文件。如果 lib 文件夹中的多个 JAR 文件包含相同的类,则使用第一个。可以使用以下 shell 脚本来识别重复类。

例 test-zip.sh

mkdir -p expanded unzip path/to/my/function.zip -d expanded find ./expanded/lib -name '*.jar' | xargs -n1 zipinfo -1 | grep '.*.class' | sort | uniq -c | sort

使用 Maven 构建部署程序包

要使用 Maven 构建部署程序包,请使用 Maven Shade 插件。该插件创建一个包含编译的函数代码及其所有依赖项的 JAR 文件。

例 pom.xml – 插件配置

<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.2</version> <configuration> <createDependencyReducedPom>false</createDependencyReducedPom> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> </execution> </executions> </plugin>

要构建部署程序包,请使用 mvn package 命令。

[INFO] Scanning for projects... [INFO] -----------------------< com.example:java-maven >----------------------- [INFO] Building java-maven-function 1.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- ... [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ java-maven --- [INFO] Building jar: target/java-maven-1.0-SNAPSHOT.jar [INFO] [INFO] --- maven-shade-plugin:3.2.2:shade (default) @ java-maven --- [INFO] Including com.amazonaws:aws-lambda-java-core:jar:1.2.1 in the shaded jar. [INFO] Including com.amazonaws:aws-lambda-java-events:jar:2.2.9 in the shaded jar. [INFO] Including joda-time:joda-time:jar:2.6 in the shaded jar. [INFO] Including com.google.code.gson:gson:jar:2.8.6 in the shaded jar. [INFO] Replacing original artifact with shaded artifact. [INFO] Replacing target/java-maven-1.0-SNAPSHOT.jar with target/java-maven-1.0-SNAPSHOT-shaded.jar [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 8.321 s [INFO] Finished at: 2020-03-03T09:07:19Z [INFO] ------------------------------------------------------------------------

此命令在 target 文件夹中生成 JAR 文件。

如果您使用 Appender 库 (aws-lambda-java-log4j2),还必须为 Maven Shade 插件配置一个转换器。转换器库合并同时出现在 Appender 库和 Log4j 中的缓存文件的版本。

例 pom.xml – 具有 Log4j 2 Appender 的插件配置

<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.2</version> <configuration> <createDependencyReducedPom>false</createDependencyReducedPom> </configuration> <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> </configuration> </execution> </executions> <dependencies> <dependency> <groupId>com.github.edwgiz</groupId> <artifactId>maven-shade-plugin.log4j2-cachefile-transformer</artifactId> <version>2.13.0</version> </dependency> </dependencies> </plugin>

使用 Lambda API 上传部署程序包

要使用 AWS CLI 或 AWS 开发工具包更新函数的代码,请使用 UpdateFunctionCode API 操作。对于 AWS CLI,请使用 update-function-code 命令。以下命令上传当前目录中名为 my-function.zip 的部署程序包。

~/my-function$ aws lambda update-function-code --function-name my-function --zip-file fileb://my-function.zip { "FunctionName": "my-function", "FunctionArn": "arn:aws:lambda:us-east-2:123456789012:function:my-function", "Runtime": "java8", "Role": "arn:aws:iam::123456789012:role/lambda-role", "Handler": "example.Handler", "CodeSha256": "Qf0hMc1I2di6YFMi9aXm3JtGTmcDbjniEuiYonYptAk=", "Version": "$LATEST", "TracingConfig": { "Mode": "Active" }, "RevisionId": "983ed1e3-ca8e-434b-8dc1-7d72ebadd83d", ... }

如果您的部署程序包大于 50 MB,则无法直接上传。将其上传到 Amazon S3 存储桶并将 Lambda 指向此对象。以下示例命令将部署程序包上传到名为 my-bucket 的存储桶,并使用它更新函数的代码。

~/my-function$ aws s3 cp my-function.zip s3://my-bucket upload: my-function.zip to s3://my-bucket/my-function ~/my-function$ aws lambda update-function-code --function-name my-function \ --s3-bucket my-bucket --s3-key my-function.zip { "FunctionName": "my-function", "FunctionArn": "arn:aws:lambda:us-east-2:123456789012:function:my-function", "Runtime": "java8", "Role": "arn:aws:iam::123456789012:role/lambda-role", "Handler": "example.Handler", "CodeSha256": "Qf0hMc1I2di6YFMi9aXm3JtGTmcDbjniEuiYonYptAk=", "Version": "$LATEST", "TracingConfig": { "Mode": "Active" }, "RevisionId": "983ed1e3-ca8e-434b-8dc1-7d72ebadd83d", ... }

您可以使用此方法上传最大为 250 MB 的函数包(已解压缩)。

使用 AWS SAM 上传部署程序包

您可以使用 AWS 无服务器应用程序模型 自动部署函数代码、配置和依赖项。AWS SAM 是 AWS CloudFormation 的一个扩展,它提供用于定义无服务器应用程序的简化语法。以下示例模板在 Gradle 使用的 build/distributions 目录中定义了一个包含部署程序包的函数。

例 template.yml

AWSTemplateFormatVersion: '2010-09-09' Transform: 'AWS::Serverless-2016-10-31' Description: An AWS Lambda application that calls the Lambda API. Resources: function: Type: AWS::Serverless::Function Properties: CodeUri: build/distributions/java-basic.zip Handler: example.Handler Runtime: java8 Description: Java function MemorySize: 512 Timeout: 10 # Function's execution role Policies: - AWSLambdaBasicExecutionRole - AWSLambdaReadOnlyAccess - AWSXrayWriteOnlyAccess - AWSLambdaVPCAccessExecutionRole Tracing: Active

要创建函数,请使用 packagedeploy 命令。这些命令是对 AWS CLI 的自定义。它们包装其他命令以将部署程序包上传到 Amazon S3,使用对象 URI 重写模板,然后更新函数的代码。

以下示例脚本运行 Gradle 构建并上传其创建的部署程序包。它在您第一次运行它时创建一个 AWS CloudFormation 堆栈。如果堆栈已经存在,脚本会更新它。

例 deploy.sh

#!/bin/bash set -eo pipefail aws cloudformation package --template-file template.yml --s3-bucket MY_BUCKET --output-template-file out.yml aws cloudformation deploy --template-file out.yml --stack-name java-basic --capabilities CAPABILITY_NAMED_IAM

有关完整的工作示例,请参阅以下示例应用程序。

Java 中的示例 Lambda 应用程序

  • blank-java – 一个 Java 函数,用于显示 Lambda 的 Java 库、日志记录、环境变量、层、AWS X-Ray 跟踪、单元测试和 AWS 开发工具包的使用情况。

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

  • java-events – 一个最小的 Java 函数,它将 aws-lambda-java-events 库与不需要 AWS 开发工具包作为依赖项的事件类型(例如 Amazon API Gateway)结合使用。

  • java-events-v1sdk – 一个 Java 函数,它将 aws-lambda-java-events 库与需要 AWS 开发工具包作为依赖项的事件类型(Amazon Simple Storage Service、Amazon DynamoDB 和 Amazon Kinesis)结合使用。

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