使用 Lambda SnapStart 處理唯一性 - AWS Lambda

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

使用 Lambda SnapStart 處理唯一性

SnapStart 函數上的呼叫擴展時,Lambda 會使用單一初始化快照來恢復多個執行環境。如果您的初始化程式碼會產生包含在快照中的唯一內容,則在跨執行環境中重複使用該內容時,該內容可能不是唯一的。若要在使用 SnapStart 時保持唯一性,您必須在初始化後產生唯一的內容。這包括唯一 ID、唯一密碼,以及用來產生偽隨機性的熵。

以下是維持程式碼唯一性的建議最佳實務。對於 Java 函數,Lambda 還提供開放原始碼 SnapStart 掃描工具,協助檢查確保唯一性的程式碼。如果您在初始化階段產生唯一資料,便可使用執行階段掛鉤來還原唯一性。使用執行階段掛鉤,您可以在 Lambda 建立快照前執行特定程式碼,或在 Lambda 從快照恢復函數後立即執行特定程式碼。

避免儲存初始化期間依賴唯一性的狀態

在函數的初始化階段,請避免快取預定為唯一的資料,例如產生用於日誌記錄的唯一 ID 或設定隨機函數的種子。相反地,建議您在函數處理常式中產生唯一的資料或設定隨機函數的種子,或使用執行時期勾點進行這些操作。

以下程式碼範例示範如何在函數處理常式中產生 UUID。

Java
範例 - 在函數處理常式中產生唯一 ID
import java.util.UUID; public class Handler implements RequestHandler<String, String> { private static UUID uniqueSandboxId = null; @Override public String handleRequest(String event, Context context) { if (uniqueSandboxId == null) uniqueSandboxId = UUID.randomUUID(); System.out.println("Unique Sandbox Id: " + uniqueSandboxId); return "Hello, World!"; } }
Python
範例 - 在函數處理常式中產生唯一 ID
import json import random import time unique_number = None def lambda_handler(event, context): seed = int(time.time() * 1000) random.seed(seed) global unique_number if not unique_number: unique_number = random.randint(1, 10000) print("Unique number: ", unique_number) return "Hello, World!"
.NET
範例 - 在函數處理常式中產生唯一 ID
namespace Example; public class SnapstartExample { private Guid _myExecutionEnvironmentGuid; public SnapstartExample() { // This GUID is set for non-restore use cases, such as testing or if SnapStart is turned off _myExecutionEnvironmentGuid = new Guid(); // Register the method which will run after each restore. You may need to update Amazon.Lambda.Core to see this Amazon.Lambda.Core.SnapshotRestore.RegisterAfterRestore(MyAfterRestore); } private ValueTask MyAfterRestore() { // After restoring this snapshot to a new execution environment, update the GUID _myExecutionEnvironmentGuid = new Guid(); return ValueTask.CompletedTask; } public string Handler() { return $"Hello World! My Execution Environment GUID is {_myExecutionEnvironmentGuid}"; } }

使用密碼編譯安全的虛擬隨機數產生器 (CSPRNGs)

如果您的應用程式依賴隨機性,建議您使用密碼編譯安全隨機數產生器 (CSPRNGs)。除了 OpenSSL 1.0.2 之外,Lambda 受管執行時期還包含以下內建 CSPRNG:

  • Java:java.security.SecureRandom

  • Python:SystemRandom

  • .NET:System.Security.Cryptography.RandomNumberGenerator

此軟體總是會從 /dev/random/dev/urandom 取得隨機數,也會透過 SnapStart 保持隨機性。

從下表指定的最低版本開始,AWS 密碼編譯程式庫會自動維持 SnapStart 的隨機性。如果您在 Lambda 函數中使用這些程式庫,請確定您使用以下最低版本或更新版本:

程式庫 支援的最低版本 (x86) 支援的最低版本 (ARM)
AWS libcrypto (AWS-LC)

1.16.0

1.30.0

AWS libcrypto FIPS

2.0.13

2.0.13

如果您透過以下程式庫將上述密碼編譯程式庫封裝為 Lambda 函數的遞移相依項,請務必使用以下最低版本或更新版本:

程式庫 支援的最低版本 (x86) 支援的最低版本 (ARM)
AWS SDK for Java 2.x

2.23.20

2.26.12

AWS Common Runtime for Java

0.29.8

0.29.25

Amazon Corretto Crypto Provider

2.4.1

2.4.1
Amazon Corretto Crypto Provider FIPS

2.4.1

2.4.1

以下範例示範如何使用 CSPRNG 來保證唯一數字序列,即使從快照還原函數也是如此。

Java
範例 – java.security.SecureRandom
import java.security.SecureRandom; public class Handler implements RequestHandler<String, String> { private static SecureRandom rng = new SecureRandom(); @Override public String handleRequest(String event, Context context) { for (int i = 0; i < 10; i++) { System.out.println(rng.next()); } return "Hello, World!"; } }
Python
範例 :random.SystemRandom
import json import random secure_rng = random.SystemRandom() def lambda_handler(event, context): random_numbers = [secure_rng.random() for _ in range(10)] for number in random_numbers: print(number) return "Hello, World!"
.NET
範例 :RandomNumberGenerator
using Amazon.Lambda.Core; using System.Security.Cryptography; [assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] namespace DotnetSecureRandom; public class Function { public string FunctionHandler() { using (RandomNumberGenerator rng = RandomNumberGenerator.Create()) { byte[] randomUnsignedInteger32Bytes = new byte[4]; for (int i = 0; i < 10; i++) { rng.GetBytes(randomUnsignedInteger32Bytes); int randomInt32 = BitConverter.ToInt32(randomUnsignedInteger32Bytes, 0); Console.WriteLine("{0:G}", randomInt32); } } return "Hello World!"; } }

SnapStart 掃描工具 (僅限 Java)

Lambda 提供 Java 掃描工具,可協助檢查確保唯一性的程式碼。SnapStart 掃描工具是一種開放原始碼 SpotBugs 外掛程式,可針對一組規則執行靜態分析。掃描工具有助於識別可能會破壞有關唯一性假設的潛在程式碼實作。如需安裝指示和掃描工具執行的檢查清單,請參閱 GitHub 上的 aws-lambda-snapstart-java-rules 儲存庫。

若要進一步了解如何使用 SnapStart 處理唯一性,請參閱 AWS 運算部落格上的使用 AWS Lambda SnapStart 加速啟動