パート 8 では Spring Cloud 関数の背後にある概念を紹介し、パート 9 では Java 21 と Spring Boot 3.2 を使用して Spring Cloud Function で AWS Lambda を開発する方法を示しました。このシリーズの記事では、Lambda 関数で SnapStart を有効にするだけでなく、DynamoDB 呼び出しのプライミングや、ネットワークを経由せずに API Gateway リクエスト全体をプライミング (プロキシ) するなど、さまざまなプライミング テクニックを適用するなど、コールド スタートとウォーム スタートの時間を測定します。 。測定には Spring Boot 3.2 サンプル アプリケーションを使用し、すべての Lambda 関数に対して JAVA_TOOL_OPTIONS: "-XX:+TieredCompilation -XX:TieredStopAtLevel=1" を使用し、Lambda 1024 MB メモリを与えます。
まず、Lambda 関数で AWS SnapStart を有効にする方法を説明します。これは (プライミングを最優先にして) Lambda パフォーマンス (特にコールドスタート時間) の最適化の可能性を最大限に高めます。それは単に設定の問題です:
SnapStart: ApplyOn: PublishedVersions
SAM テンプレートの Lambda 関数プロパティまたはグローバル関数セクションに適用されます。私たちのユースケースで SnpaStart に加えてさまざまなプライミング技術を使用する方法をさらに詳しく説明したいと思います。プライミングの背後にある考え方については、記事「AWS Lambda SnapStart - プライミング、エンドツーエンドのレイテンシー、デプロイメント時間の測定
」で説明しました。1) DynamoDB リクエストのプライミング用のコードはここにあります。
このクラスは、CraC プロジェクトの import org.crac.Resource インターフェイスをさらに実装します。
この呼び出しにより
Core.getGlobalContext().register(this);
GetProductByIdWithDynamoDBRequestPrimingHandler クラスは、それ自体を CRaC リソースとして登録します。
CRaC API から beforeCheckpoint メソッドを実装することで、DynamoDB の呼び出しをさらに準備します。
@Override public void beforeCheckpoint(org.crac.Context<? extends Resource> context) throws Exception { productDao.getProduct("0"); }
これは、Lambda 関数のデプロイメント段階中、Firecracker microVM スナップショットが取得される前に呼び出されます。
2) API Gateway リクエスト全体のプライミング用のコードは、ここにあります。
このクラスは、上記の例のように import org.crac.Resource インターフェースも追加で実装します。
私の記事「AWS Lambda SnapStart - パート 6 Java 11 および Micronaut、Quarkus、Spring Boot フレームワークのリクエスト呼び出しのプライミング」で説明した醜いテクニックを再利用します。この手法を本番環境で使用することはお勧めしませんが、Spring Boot モデルと Spring Cloud Function モデルの間のマッピングと DynamoDB も実行する Lambda モデルを事前にロードすることにより、API Gateway リクエスト全体のプライミングを使用してコールド スタートを削減できる可能性をさらに実証します。呼び出しのプライミング
ID が 0 の /products/{id} の API ゲートウェイ リクエスト構築 API ゲートウェイ JSON リクエストは次のようになります。
private static String getAPIGatewayRequestMultiLine () { return """ { "resource": "/products/{id}", "path": "/products/0", "httpMethod": "GET", "pathParameters": { "id": "0" }, "requestContext": { "identity": { "apiKey": "blabla" } } } """; }
API の入力ストリームを渡すことで handleRequest メソッドを呼び出す Spring Cloud Function の FunctionInvoker クラスを使用して、ネットワークを経由せずに API Gateway リクエスト全体をプライム (プロキシ) するときの beforeCheckpoint上記のように構築されたゲートウェイ JSON リクエスト:
@Override public void beforeCheckpoint(org.crac.Context<? extends Resource> context) throws Exception { new FunctionInvoker().handleRequest( new ByteArrayInputStream(getAPIGatewayRequestMultiLine(). getBytes(StandardCharsets.UTF_8)), new ByteArrayOutputStream(), new MockLambdaContext()); }
以下の実験の結果は、1024 MB のメモリ設定で Lambda 関数を使用して 100 回を超えるコールド スタートと約 100,000 回のウォーム スタートを 1 時間にわたって再現したことに基づいています。このために負荷テスト ツールを使用しましたが、Serverless-artillery や Postman など、好きなツールを使用できます。
これらすべての実験を 4 つの異なるシナリオで実行しました:
1) SnapStart が有効になっていません
template.yaml で次の構成を使用します:
Handler: org.springframework.cloud.function.adapter.aws.FunctionInvoker::handleRequest #SnapStart: #ApplyOn: PublishedVersions
そして、GetProductByIdHandler Lambda Handler Java クラスにマップされる GetProductByIdWithSpringBoot32SCF という名前の Lambda 関数を呼び出す必要があります。
2) SnapStart は有効ですが、プライミングは適用されていません
template.yaml で次の構成を使用します:
Handler: org.springframework.cloud.function.adapter.aws.FunctionInvoker::handleRequest SnapStart: ApplyOn: PublishedVersions
そして、GetProductByIdHandler Lambda Handler Java クラスにマップされる GetProductByIdWithSpringBoot32SCF という名前の同じ Lambda 関数を呼び出す必要があります。
3) DynamoDB 呼び出しプライミングで SnapStart が有効化
template.yaml で次の構成を使用します:
Handler: org.springframework.cloud.function.adapter.aws.FunctionInvoker::handleRequest SnapStart: ApplyOn: PublishedVersions
そして、GetProductByIdWithDynamoDBRequestPrimingHandler Lambda Handler Java クラスにマップされる GetProductByIdWithSpringBoot32SCFAndDynamoDBRequestPriming という名前の Lambda 関数を呼び出す必要があります。
4) API Gateway リクエスト呼び出しのプライミング/プロキシで SnapStart が有効になっている
template.yaml で次の構成を使用します:
Handler: org.springframework.cloud.function.adapter.aws.FunctionInvoker::handleRequest SnapStart: ApplyOn: PublishedVersions
and we need to invoke Lambda function with name
GetProductByIdWithSpringBoot32SCFAndWebRequestPriming which is mapped to the GetProductByIdWithWebRequestPrimingHandler Lambda Handler Java class.
Abbreviation c is for the cold start and w is for the warm start.
Cold (c) and warm (w) start time in ms:
Scenario Number | c p50 | c p75 | c p90 | c p99 | c p99.9 | c max | w p50 | w p75 | w p90 | w p99 | w p99.9 | w max |
---|---|---|---|---|---|---|---|---|---|---|---|---|
No SnapStart enabled | 4768.34 | 4850.11 | 4967.86 | 5248.61 | 5811.92 | 5813.31 | 7.16 | 8.13 | 9.53 | 21.75 | 62.00 | 1367.52 |
SnapStart enabled but no priming applied | 2006.60 | 2065.61 | 2180.17 | 2604.69 | 2662.60 | 2663.54 | 7.45 | 8.40 | 9.92 | 23.09 | 1354.50 | 1496.46 |
SnapStart enabled with DynamoDB invocation priming | 1181.40 | 1263.23 | 1384.90 | 1533.54 | 1661.20 | 1662.17 | 7.57 | 8.73 | 10.83 | 23.83 | 492.37 | 646.18 |
SnapStart enabled with API Gateway request invocation priming | 855.45 | 953.91 | 1107.10 | 1339.97 | 1354.78 | 1355.21 | 8.00 | 9.53 | 12.09 | 26.31 | 163.26 | 547.28 |
By enabling SnapStart on the Lambda function alone, it reduces the cold start time of the Lambda function significantly. By additionally using DynamoDB invocation priming we are be able to achieve cold starts only slightly higher than cold starts described in my article AWS SnapStart -Measuring cold and warm starts with Java 21 using different memory settings where we measured cold and warm starts for the pure Lambda function without the usage of any frameworks including 1024MB memory setting like in our scenario.
Comparing the cold and warm start times we measured with AWS Serverless Java Container in the article Measuring cold and warm starts with AWS Serverless Java Container and Measuring cold and warm starts with AWS Lambda Web Adapter we observe that Spring Cloud Function offers higher cold start times than AWS Lambda Web Adapter but quite comparable cold start times to AWS Serverless Java Container (results vary slightly depending on the percentiles). In terms of warm start/execution times all 3 approaches have quite comparable results when especially looking into the percentiles below 99.9.
以上がAWS Lambda での Spring Boot アプリケーション - パート Spring Cloud Function を使用したコールド スタートとウォーム スタートの測定の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。