Lambda マネージドインスタンスの Rust サポート
同時実行数の設定
Lambda が各実行環境に送信する同時リクエストの最大数は、関数設定の PerExecutionEnvironmentMaxConcurrency 設定で制御できます。これはオプション設定です。Rust のデフォルト値は vCPU ごとに 8 つの同時リクエストですが、独自の値を設定することも可能です。この値は、ランタイムによってスポーンされた Tokio タスクの数を決定するもので、実行環境の存続期間中は固定 (静的) となります。各ワーカーは実行中のリクエストを 1 つだけ処理し、多重処理することはありません。Lambda は、各実行環境の容量に応じて、設定された最大数までの同時リクエストの数を自動的に調整し、それらのリクエストを取得します。
同時実行のための関数の構築
Lambda マネージドインスタンスを使用する場合は、他のマルチスレッド環境と同じスレッドセーフな環境を適用する必要があります。ハンドラーオブジェクトはすべてのワーカースレッドで共有されるため、ミュータブルな状態はスレッドセーフである必要があります。これには、コレクション、データベース接続、およびリクエスト処理中に変更される静的オブジェクトが含まれます。
同時リクエスト処理を有効にするには、 concurrency-tokio 機能フラグを Cargo.toml ファイルに追加します。
[dependencies] lambda_runtime = { version = "1", features = ["concurrency-tokio"] }
lambda_runtime::run_concurrent(…) エントリポイントは、通常メイン関数の #[tokio::main] 属性によって提供される Tokio ランタイム内から呼び出す必要があります。ハンドラークロージャは CloneSend
呼び出し間で共有される状態 (データベース接続プールや設定構造体など) が必要な場合は、それを ArcArc をクローンします。
すべての AWS SDK for Rust クライアントは同時実行セーフであり、特別な処理は必要ありません。
例: AWS SDK クライアント
次の例では、S3 クライアントを使用して、呼び出しごとにオブジェクトをアップロードします。クライアントは、Arc を介さず、直接クロージャ内へクローンされます。
let config = aws_config::load_defaults(BehaviorVersion::latest()).await; let s3_client = aws_sdk_s3::Client::new(&config); run_concurrent(service_fn(move |event: LambdaEvent<Request>| { let s3_client = s3_client.clone(); // cheap clone, no Arc needed async move { s3_client.put_object() .bucket(&event.payload.bucket) .key(&event.payload.key) .body(event.payload.body.into_bytes().into()) .send() .await?; Ok(Response { message: "uploaded".into() }) } })) .await
例: データベース接続プール
クライアントや設定などの共有状態にハンドラからアクセスする必要がある場合は、それらを ArcArc をクローンします。
#[derive(Debug)] struct AppState { dynamodb_client: DynamoDbClient, table_name: String, cache_ttl: Duration, } let config = aws_config::load_defaults(BehaviorVersion::latest()).await; let state = Arc::new(AppState { dynamodb_client: DynamoDbClient::new(&config), table_name: std::env::var("TABLE_NAME").expect("TABLE_NAME must be set"), cache_ttl: Duration::from_secs(300), }); run_concurrent(service_fn(move |event: LambdaEvent<Request>| { let state = state.clone(); async move { handle(event, state).await } })) .await
共有の /tmp ディレクトリ
/tmp ディレクトリは、実行環境内のすべての同時呼び出し間で共有されます。呼び出しごとに一意のファイル名 (例えばリクエスト ID を含める) を使用するか、明示的なファイルロックを実装してデータの破損を回避します。
ログ記録
ログインターリービング (ログでインターリーブされるさまざまなリクエストからのログエントリ) は、複数同時実行システムでは正常です。Lambda マネージドインスタンスを使用する関数は、Lambda の高度なログ記録コントロールを通じて、構造化された JSON ログ形式をサポートします。この形式には requestId が含まれ、ログエントリを 1 つのリクエストに関連付けることができます。詳細については、「トレーシングクレートによる高度なログ記録機能の実装」を参照してください。
リクエストコンテキスト
Context オブジェクトは各ハンドラー呼び出しに直接渡されます。event.context.request_id を使用して、現在のリクエストのリクエスト ID にアクセスします。
event.context.xray_trace_id を使用して X-Ray トレース ID にアクセスします。Lambda は、Lambda マネージドインスタンスの _X_AMZN_TRACE_ID 環境変数をサポートしていません。AWS SDK for Rust を使用すると、X-Ray トレース ID が自動的に伝播されます。
event.context.deadline を使用してタイムアウトを検出します。これには、呼び出しの期限がミリ秒単位で含まれます。
初期化とシャットダウン
関数の初期化は、実行環境ごとに 1 回行われます。初期化中に作成されたオブジェクトは、リクエスト間で共有されます。
拡張機能を持つ Lambda 関数の場合、実行環境はシャットダウン中に SIGTERM シグナルを出力します。このシグナルは、バッファのフラッシュなどのクリーンアップタスクをトリガーするために拡張機能で使用されます。 lambda_runtime は、グレースフルシャットダウンのシグナル処理の設定を簡略化するヘルパー関数 spawn_graceful_shutdown_handler()
依存関係バージョン
Lambda マネージドインスタンスには、以下のパッケージバージョンの最小要件が必要です。
-
lambda_runtime: バージョン 1.1.1 以降 (concurrency-tokio機能が有効であること) -
最小サポート Rust バージョン (MSRV) は 1.84.0 です。