

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 縮短 的 SDK 啟動時間 AWS Lambda
<a name="lambda-optimize-starttime"></a>

的其中一個目標是 AWS SDK for Java 2.x 降低 函數的 AWS Lambda 啟動延遲。開發套件包含減少啟動時間的變更，本主題結束時會討論這些變更。

首先，本主題著重於您可以進行的變更，以減少冷啟動時間。這包括在您的程式碼結構和服務用戶端的組態中進行變更。

## 使用 AWS CRT 型 HTTP 用戶端
<a name="lambda-quick-url"></a>

若要使用 AWS Lambda，我們建議[https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/crt/AwsCrtHttpClient.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/crt/AwsCrtHttpClient.html)同步案例使用 ，[https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/crt/AwsCrtAsyncHttpClient.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/crt/AwsCrtAsyncHttpClient.html)非同步案例則使用 。

本指南中的[設定 AWS CRT 型 HTTP 用戶端](http-configuration-crt.md)主題說明使用 HTTP 用戶端的優點、如何新增相依性，以及如何設定服務用戶端使用它們。

## 移除未使用的 HTTP 用戶端相依性
<a name="lambda-quick-remove-deps"></a>

除了明確使用 AWS CRT 型用戶端之外，您還可以移除軟體開發套件預設引入的其他 HTTP 用戶端。當需要載入的程式庫較少時，Lambda 啟動時間會縮短，因此您應該移除 JVM 需要載入的任何未使用成品。

Maven `pom.xml` 檔案的下列程式碼片段顯示排除 Apache 型 HTTP 用戶端和 Netty 型 HTTP 用戶端。（當您使用 AWS CRT 型用戶端時，不需要這些用戶端。) 此範例會從 S3 用戶端相依性中排除 HTTP 用戶端成品，並新增`aws-crt-client`成品以允許存取 AWS CRT 型 HTTP 用戶端。

```
<project>
    <properties>
        <aws.java.sdk.version>2.27.21</aws.java.sdk.version>
    <properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>software.amazon.awssdk</groupId>
                <artifactId>bom</artifactId>
                <version>${aws.java.sdk.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>aws-crt-client</artifactId>
        </dependency>
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>s3</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>software.amazon.awssdk</groupId>
                    <artifactId>netty-nio-client</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>software.amazon.awssdk</groupId>
                    <artifactId>apache-client</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
</project>
```

**注意**  
將 `<exclusions>`元素新增至 `pom.xml` 檔案中的所有服務用戶端相依性。

## 將服務用戶端設定為捷徑查詢
<a name="lambda-quick-clients"></a>

**指定區域**  
當您建立服務用戶端時，請在服務用戶端建置器上呼叫 `region`方法。這會捷徑化軟體開發套件的預設[區域查詢程序](region-selection.md#default-region-provider-chain)，以檢查多個位置 AWS 區域 的資訊。  
若要讓 Lambda 程式碼獨立於 區域，請在 `region`方法中使用下列程式碼。此程式碼會存取 Lambda 容器設定`AWS_REGION`的環境變數。  

```
Region.of(System.getenv(SdkSystemSetting.AWS_REGION.environmentVariable()))
```

**使用 `EnvironmentVariableCredentialProvider`**  
就像區域資訊的預設查詢行為一樣，軟體開發套件會在多個位置尋找登入資料。透過在建置服務用戶端[https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/auth/credentials/EnvironmentVariableCredentialsProvider.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/auth/credentials/EnvironmentVariableCredentialsProvider.html)時指定 ，您可以在 SDK 的查詢程序中為登入資料節省時間。  
使用此登入資料提供者可讓程式碼用於 Lambda 函數，但可能無法在 Amazon EC2 或其他系統上運作。  
如果您打算在某個時間點使用 [Lambda SnapStart for Java](#lambda-quick-snapstart)，您應該依賴預設登入資料提供者鏈結來查詢登入資料。如果您指定 `EnvironmentVariableCredentialsProvider`，初始登入資料查詢會正常運作，但啟用 SnapStart 時，[Java 執行時間會設定容器登入資料環境變數](https://docs.aws.amazon.com/lambda/latest/dg/snapstart-activate.html#snapstart-credentials)。啟用時，`EnvironmentVariableCredentialsProvider`Java SDK 無法使用存取金鑰環境變數所使用的環境變數。

下列程式碼片段顯示已適當設定用於 Lambda 環境的 S3 服務用戶端。

```
S3Client s3Client = S3Client.builder()
    .region(Region.of(System.getenv(SdkSystemSetting.AWS_REGION.environmentVariable())))
    .credentialsProvider(EnvironmentVariableCredentialsProvider.create())
    .httpClient(AwsCrtHttpClient.builder().build())
    .build();
```

## 在 Lambda 函數處理常式外部初始化 SDK 用戶端
<a name="lambda-quick-initialize"></a>

我們建議在 Lambda 處理常式方法之外初始化 SDK 用戶端。如此一來，如果重複使用執行內容，就可以略過服務用戶端的初始化。透過重複使用用戶端執行個體及其連線，後續呼叫處理常式方法的速度會更快。

在下列範例中，會使用靜態原廠方法在建構函數中初始化`S3Client`執行個體。如果重複使用由 Lambda 環境管理的容器，則會重複使用初始化的`S3Client`執行個體。

```
public class App implements RequestHandler<Object, Object> {
    private final S3Client s3Client;

    public App() {
        s3Client = DependencyFactory.s3Client();
    }

    @Override
    public Object handle Request(final Object input, final Context context) {
         ListBucketResponse response = s3Client.listBuckets();
         // Process the response.
    }
}
```

## 將相依性插入降到最低
<a name="lambda-quick-di"></a>

相依性注入 (DI) 架構可能需要額外的時間來完成設定程序。它們也可能需要額外的相依性，這需要一些時間才能載入。

如果需要 DI 架構，建議您使用輕量型 DI 架構，例如 [Dagger](https://dagger.dev/dev-guide/)。

## 使用 Maven 原型目標 AWS Lambda
<a name="lambda-quick-maven"></a>

 AWS Java SDK 團隊已開發 [Maven Archetype](https://github.com/aws/aws-sdk-java-v2/tree/master/archetypes/archetype-lambda) 範本，以最短的啟動時間引導 Lambda 專案。您可以從原型建置 Maven 專案，並知道相依性已針對 Lambda 環境適當設定。

若要進一步了解原型並進行範例部署，請參閱此[部落格文章](https://aws.amazon.com/blogs/developer/bootstrapping-a-java-lambda-application-with-minimal-aws-java-sdk-startup-time-using-maven/)。

## 考慮 Lambda SnapStart for Java
<a name="lambda-quick-snapstart"></a>

如果您的執行時間需求相容， AWS 請提供適用於 [Java 的 Lambda SnapStart](https://docs.aws.amazon.com/lambda/latest/dg/snapstart.html)。Lambda SnapStart 是以基礎設施為基礎的解決方案，可改善 Java 函數的啟動效能。當您發佈新版本的函數時，Lambda SnapStart 會初始化該函數，並取得記憶體和磁碟狀態的不可變、加密快照。然後，SnapStart 會快取快照以供重複使用。

## 影響啟動時間的 2.x 版變更
<a name="example-client-configuration"></a>

除了您對程式碼所做的變更之外，適用於 Java 的 開發套件 2.x 版還包含三個主要變更，可縮短啟動時間：
+ 使用 [jackson-jr](https://github.com/FasterXML/jackson-jr)，這是一個序列化程式庫，可縮短初始化時間
+ 將 [java.time](https://docs.oracle.com/javase/8/docs/api/index.html?java/time.html) 程式庫用於日期和時間物件，這是 JDK 的一部分
+ 使用 [Slf4j](https://www.slf4j.org/) 記錄外觀

## 其他資源
<a name="lambda-quick-resources"></a>

 AWS Lambda 開發人員指南包含開發非 Java 特定 Lambda 函數[最佳實務的章節](https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html)。

如需在 Java 中使用 建置雲端原生應用程式的範例 AWS Lambda，請參閱此[研討會內容](https://github.com/aws-samples/aws-lambda-java-workshop)。研討會討論效能最佳化和其他最佳實務。

您可以考慮使用預先編譯的靜態映像，以減少啟動延遲。例如，您可以使用適用於 Java 的 SDK 2.x 和 Maven 來[建置 GraalVM 原生映像](setup-project-graalvm.md)。