使用 .zip 或 JAR 封存檔部署 Java Lambda 函數 - AWS Lambda

使用 .zip 或 JAR 封存檔部署 Java Lambda 函數

您的 AWS Lambda 函數的程式碼由指令碼或編譯程式及其相依項所組成。使用部署套件將函數程式碼部署到 Lambda。Lambda 支援兩種類型的部署套件:容器映像和 .zip 封存檔。

本頁說明如何以 .zip 檔案或 Jar 檔案的形式建立部署套件,然後透過 AWS Lambda (AWS Command Line Interface) 使用部署套件,將函數程式碼部署至 AWS CLI。

先決條件

AWS CLI 是開放原始碼工具,可讓您在命令列 shell 中使用命令來與 AWS 服務互動。若要完成本節中的步驟,您必須執行下列各項:

工具與程式庫

Lambda 提供下列適用於 Java 函數的程式庫:

這些程式庫可透過 Maven Central Repository 取得。請將它們新增到您的建置定義中,如下所示︰

Gradle
dependencies { implementation 'com.amazonaws:aws-lambda-java-core:1.2.1' implementation 'com.amazonaws:aws-lambda-java-events:3.11.0' runtimeOnly 'com.amazonaws:aws-lambda-java-log4j2:1.5.1' }
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.11.0</version> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-log4j2</artifactId> <version>1.5.1</version> </dependency> </dependencies>

若要建立部署套件,請將函數程式碼和相依性編譯成單一 .zip 檔案或 Java 封存 (JAR) 檔案。針對 Gradle,請使用Zip建置類型。針對 Apache Maven,請使用 Maven Shade 外掛程式

注意

若要將您部署套件大小保持較小,請以階層方式將您的函式相依項目進行封裝。各層可讓您獨立管理相依項目,並可供多個函數使用,也可和其他帳戶共用。如需更多詳細資訊,請參閱 建立和共用 Lambda 層

您可以使用 Lambda 主控台、Lambda API 或 AWS Serverless Application Model (AWS SAM) 上傳部署套件。

使用 Lambda 主控台上傳部署套件

  1. 開啟 Lambda 主控台中的 Functions (函數) 頁面

  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.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 檔案包含相同類別,則會使用第一個 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.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 檔案。

如果您使用附加器程式庫 (aws-lambda-java-log4j2),則還必須配置 Maven Shade 外掛程式的轉換器。轉換器程式庫會合併出現在附加器程式庫和 Log4j 中快取檔案的版本。

範例 pom.xml - 具備 Log4j 2 附加器的外掛程式組態

<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 Command Line Interface (AWS CLI) 或 AWS 開發套件更新函數的程式碼,請使用 UpdateFunctionCode API 操作。若是 AWS 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 的函數套件 (解壓縮)。

使用 AWS SAM 上傳部署套件

您可以使用 AWS SAM 來自動部署函數程式碼、組態和相依性。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 - AWSLambda_ReadOnlyAccess - 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 - 使用 aws-lambda-java-events 程式庫最新版本 (3.0.0 及更新版本) 的最小 Java 函數。這些範例不需要 AWS 開發套件做為相依項目。

  • s3-java - 一種 Java 函數,它處理來自 Amazon S3 的通知事件,並使用 Java Class Library (JCL) 以從上傳的映像檔案建立縮圖。