使用 .zip 或 JAR 文件归档部署 Java Lambda 函数
您的 Amazon Lambda 函数代码由脚本或编译的程序及其依赖项组成。您可以使用部署程序包将函数代码部署到 Lambda。Lambda 支持两种类型的部署程序包:容器镜像和 .zip 文件归档。
本页将介绍如何将部署程序包创建为 .zip 文件或 Jar 文件,然后使用该部署程序包通过 Amazon Lambda (Amazon Command Line Interface) 将函数代码部署到 Amazon CLI。
先决条件
Amazon CLI 是一种开源工具,让您能够在命令行 Shell 中使用命令与 Amazon 服务进行交互。要完成本节中的步骤,您必须满足以下条件:
工具和库
Lambda 提供以下适用于 Java 函数的库:
-
com.amazonaws:aws-lambda-java-core
(必需)– 定义处理程序方法接口和运行时传递给处理程序的上下文对象。如果您定义自己的输入类型,则这是您唯一需要的库。 -
com.amazonaws:aws-lambda-java-events
– 调用 Lambda 函数服务的事件的输入类型。 -
com.amazonaws:aws-lambda-java-log4j2
– Apache Log4j 2 的 Appender 库,可用于将当前调用的请求 ID 添加到函数日志中。 -
适用于 Java 2.0 的Amazon开发工具包
– 适用于 Java 编程语言的官方Amazon开发工具包。
这些库可通过 Maven 中央存储库
要创建部署程序包,请将函数代码和依赖项编译成单个 .zip 文件或 Java 存档 (JAR) 文件。对于 Gradle,请使用 Zip 构建类型。对于 Apache Maven,请使用 Maven Shade 插件。
为了减小部署程序包的大小,请将函数的依赖项打包到层中。层可让您独立管理依赖项,可供多个函数使用,并可与其他账户共享。有关更多信息,请参阅创建和共享 Lambda 层。
您可以使用 Lambda 控制台、Lambda API 或 Amazon Serverless Application Model (Amazon SAM) 上载部署程序包。
使用 Lambda 控制台上载部署程序包
打开 Lamba 控制台的 Functions(函数)页面
。 -
选择函数。
-
在 Code source(代码源)下,选择 Upload from(上传自)。
-
构建部署程序包。
-
选择保存。
使用 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.11.0'
implementation 'com.google.code.gson:gson:2.8.6' implementation 'org.apache.logging.log4j:log4j-api:2.17.1' implementation 'org.apache.logging.log4j:log4j-core:2.17.1' runtimeOnly 'org.apache.logging.log4j:log4j-slf4j18-impl:2.17.1'runtimeOnly 'com.amazonaws:aws-lambda-java-log4j2:1.5.1'
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 插件
例 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.11.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: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 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: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 的函数包(已解压缩)。
使用 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
要创建函数,请使用 package
和 deploy
命令。这些命令是对 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 库的最新版本(3.0.0 及更高版本)。这些示例不需要Amazon开发工具包作为依赖项。 -
s3-java
– 此 Java 函数可处理来自 Amazon S3 的通知事件,并使用 Java 类库 (JCL) 从上载的图像文件创建缩略图。