使用 .zip 或 JAR 文件存档部署 Java Lambda 函数 - Amazon Lambda
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 Amazon Web Services 服务入门

使用 .zip 或 JAR 文件存档部署 Java Lambda 函数

您的 Amazon Lambda 函数代码由脚本或编译的程序及其依赖项组成。您可以使用部署程序包来将函数代码部署到 Lambda。Lambda 支持两种类型的部署程序包:容器映像和 .zip 文件存档。

本页将介绍如何将部署程序包创建为 .zip 文件或 Jar 文件,然后使用该部署程序包通过 Amazon Command Line Interface (Amazon CLI) 将函数代码部署到 Amazon Lambda。

小节目录

先决条件

Amazon CLI 是一种开源工具,让您能够在命令行 Shell 中使用命令与 Amazon 服务进行交互。要完成本节中的步骤,您必须满足以下条件:

工具和库

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

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

Gradle
dependencies { implementation 'com.amazonaws:aws-lambda-java-core:1.2.1' implementation 'com.amazonaws:aws-lambda-java-events:3.1.0' 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>3.1.0</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 构建类型。对于 Apache Maven,请使用 Maven Shade 插件

注意

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

您可以使用 Lambda 控制台、Lambda API 或 Amazon Serverless Application Model (Amazon SAM) 上传部署程序包。

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

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

  2. 选择函数。

  3. Code source(代码源)下,选择 Upload from(上传自)

  4. 构建部署程序包。

  5. 选择 Save

使用 Gradle 构建部署程序包

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

例 build.gradle – 构建任务

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

此构建配置在 build/distributions 目录中生成部署程序包。compileJava 任务编译函数的类。该 processResources 任务会将 Java 项目资源复制到目标目录中,然后可能会进行处理。接着,语句 into('lib') 将依赖项库从构建的类路径复制到名为 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:3.1.0' 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:3.1.0 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 上传部署程序包

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

aws lambda update-function-code --function-name my-function --zip-file fileb://my-function.zip

您应看到以下输出:

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

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

aws s3 cp my-function.zip s3://my-bucket

您应看到以下输出:

upload: my-function.zip to s3://my-bucket/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-cn:lambda:us-east-2:123456789012:function:my-function", "Runtime": "java8", "Role": "arn:aws-cn:iam::123456789012:role/lambda-role", "Handler": "example.Handler", "CodeSha256": "Qf0hMc1I2di6YFMi9aXm3JtGTmcDbjniEuiYonYptAk=", "Version": "$LATEST", "TracingConfig": { "Mode": "Active" }, "RevisionId": "983ed1e3-ca8e-434b-8dc1-7d72ebadd83d", ... }

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

使用 Amazon SAM 上传部署程序包

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

例 template.yml

AWSTemplateFormatVersion: '2010-09-09' Transform: 'AWS::Serverless-2016-10-31' Description: An Amazon 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 - AWSLambda_ReadOnlyAccess - AWSXrayWriteOnlyAccess - AWSLambdaVPCAccessExecutionRole Tracing: Active

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

以下示例脚本运行 Gradle 构建并上传其创建的部署程序包。它在您第一次运行它时创建一个 Amazon 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 库、日志记录、环境变量、层、Amazon X-Ray 跟踪、单元测试和 Amazon 开发工具包的使用情况。

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

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

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

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