Kompilieren Sie.NET-Lambda-Funktionscode in ein natives Laufzeitformat - AWS Lambda

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Kompilieren Sie.NET-Lambda-Funktionscode in ein natives Laufzeitformat

.NET 8 unterstützt die native Kompilierung ahead-of-time (AOT). Mit nativem AOT können Sie Ihren Lambda-Funktionscode in ein natives Laufzeitformat kompilieren, wodurch die Notwendigkeit entfällt, .NET-Code zur Laufzeit zu kompilieren. Die native AOT-Kompilierung kann die Kaltstartzeit für Lambda-Funktionen reduzieren, die Sie in .NET schreiben. Weitere Informationen finden Sie im AWS Compute-Blog unter Einführung in die .NET 8-Laufzeit für AWS Lambda.

Lambda-Laufzeit

Verwenden Sie die verwaltete .NET 8-Lambda-Laufzeit, um einen Lambda-Funktionsbuild mit nativer AOT-Kompilierung bereitzustellen. Diese Laufzeit unterstützt die Verwendung von x86_64- und arm64-Architekturen.

Wenn Sie eine.NET-Lambda-Funktion ohne AOT bereitstellen, wird Ihre Anwendung zunächst in Intermediate Language (IL) -Code kompiliert. Zur Laufzeit nimmt der just-in-time (JIT-) Compiler in der Lambda-Laufzeit den IL-Code und kompiliert ihn nach Bedarf in Maschinencode. Mit einer Lambda-Funktion, die im Voraus mit nativem AOT kompiliert wird, kompilieren Sie Ihren Code bei der Bereitstellung Ihrer Funktion in Maschinencode, sodass Sie nicht auf die .NET-Laufzeit oder das SDK in der Lambda-Laufzeit angewiesen sind, um Ihren Code vor der Ausführung zu kompilieren.

Eine Einschränkung von AOT besteht darin, dass Ihr Anwendungscode in einer Umgebung mit demselben Amazon Linux 2023 (AL2023) -Betriebssystem kompiliert werden muss, das von.NET 8-Runtime verwendet wird. Die.NET Lambda-CLI bietet Funktionen zum Kompilieren Ihrer Anwendung in einem Docker-Container mithilfe eines AL2023-Images.

Um mögliche Probleme mit der architekturübergreifenden Kompatibilität zu vermeiden, empfehlen wir dringend, dass Sie Ihren Code in einer Umgebung mit derselben Prozessorarchitektur kompilieren, die Sie für Ihre Funktion konfigurieren. Weitere Informationen zu den Einschränkungen der architekturübergreifenden Kompilierung finden Sie unter Cross-Compilierung in der Microsoft.NET-Dokumentation.

Voraussetzungen

Docker

Um natives AOT verwenden zu können, muss Ihr Funktionscode in einer Umgebung mit demselben AL2023-Betriebssystem kompiliert werden wie das.NET 8-Runtime. Die .NET-CLI-Befehle in den folgenden Abschnitten verwenden Docker, um Lambda-Funktionen in einer AL203-Umgebung zu entwickeln und zu erstellen.

.NET 8 SDK

Die native AOT-Kompilierung ist ein Feature von.NET 8. Sie müssen das.NET 8-SDK auf Ihrem Build-Computer installieren, nicht nur auf der Runtime.

Amazon.Lambda.Tools

Verwenden Sie zum Erstellen Ihrer Lambda-Funktionen die Amazon.Lambda.Tools-.NET Global Tools-Erweiterung. Um Amazon.Lambda.Tools zu installieren, führen Sie den folgenden Befehl aus:

dotnet tool install -g Amazon.Lambda.Tools

Weitere Informationen zur Amazon.Lambda.Tools .NET-CLI-Erweiterung finden Sie im AWS Extensions for .NET CLI-Repository unter GitHub.

Amazon.Lambda.Templates

Verwenden Sie das Amazon.Lambda.Templates NuGet Paket, um Ihren Lambda-Funktionscode zu generieren. Zur Installation dieses Vorlagenpakets führen Sie den folgenden Befehl aus:

dotnet new install Amazon.Lambda.Templates

Erste Schritte

Sowohl das.NET Global CLI als auch AWS Serverless Application Model (AWS SAM) bieten Vorlagen für erste Schritte zum Erstellen von Anwendungen mit nativem AOT. Um Ihre erste native AOT-Lambda-Funktion zu erstellen, führen Sie die Schritte in den folgenden Anweisungen aus.

Um eine native AOT-kompilierte Lambda-Funktion zu initialisieren und bereitzustellen
  1. Initialisieren Sie ein neues Projekt unter Verwendung der nativen AOT-Vorlage und navigieren Sie dann in das Verzeichnis, das die erstellten .cs- und .csproj-Dateien enthält. In diesem Beispiel nennen wir unsere Funktion NativeAotSample.

    dotnet new lambda.NativeAOT -n NativeAotSample cd ./NativeAotSample/src/NativeAotSample

    Die von der nativen AOT-Vorlage erstellte Function.cs-Datei enthält den folgenden Funktionscode.

    using Amazon.Lambda.Core; using Amazon.Lambda.RuntimeSupport; using Amazon.Lambda.Serialization.SystemTextJson; using System.Text.Json.Serialization; namespace NativeAotSample; public class Function { /// <summary> /// The main entry point for the Lambda function. The main function is called once during the Lambda init phase. It /// initializes the .NET Lambda runtime client passing in the function handler to invoke for each Lambda event and /// the JSON serializer to use for converting Lambda JSON format to the .NET types. /// </summary> private static async Task Main() { Func<string, ILambdaContext, string> handler = FunctionHandler; await LambdaBootstrapBuilder.Create(handler, new SourceGeneratorLambdaJsonSerializer<LambdaFunctionJsonSerializerContext>()) .Build() .RunAsync(); } /// <summary> /// A simple function that takes a string and does a ToUpper. /// /// To use this handler to respond to an AWS event, reference the appropriate package from /// https://github.com/aws/aws-lambda-dotnet#events /// and change the string input parameter to the desired event type. When the event type /// is changed, the handler type registered in the main method needs to be updated and the LambdaFunctionJsonSerializerContext /// defined below will need the JsonSerializable updated. If the return type and event type are different then the /// LambdaFunctionJsonSerializerContext must have two JsonSerializable attributes, one for each type. /// // When using Native AOT extra testing with the deployed Lambda functions is required to ensure // the libraries used in the Lambda function work correctly with Native AOT. If a runtime // error occurs about missing types or methods the most likely solution will be to remove references to trim-unsafe // code or configure trimming options. This sample defaults to partial TrimMode because currently the AWS // SDK for .NET does not support trimming. This will result in a larger executable size, and still does not // guarantee runtime trimming errors won't be hit. /// </summary> /// <param name="input"></param> /// <param name="context"></param> /// <returns></returns> public static string FunctionHandler(string input, ILambdaContext context) { return input.ToUpper(); } } /// <summary> /// This class is used to register the input event and return type for the FunctionHandler method with the System.Text.Json source generator. /// There must be a JsonSerializable attribute for each type used as the input and return type or a runtime error will occur /// from the JSON serializer unable to find the serialization information for unknown types. /// </summary> [JsonSerializable(typeof(string))] public partial class LambdaFunctionJsonSerializerContext : JsonSerializerContext { // By using this partial class derived from JsonSerializerContext, we can generate reflection free JSON Serializer code at compile time // which can deserialize our class and properties. However, we must attribute this class to tell it what types to generate serialization code for. // See https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-source-generation

    Native AOT kompiliert Ihre Anwendung in eine einzige native Binärdatei. Der Einstiegspunkt dieser Binärdatei ist die static Main-Methode. Innerhalb von static Main wird die Lambda-Laufzeit gebootstrapped und die FunctionHandler-Methode eingerichtet. Als Teil des Runtime-Bootstrap wird ein quellgenerierter Serializer mit new SourceGeneratorLambdaJsonSerializer<LambdaFunctionJsonSerializerContext>() konfiguriert

  2. Um Ihre Anwendung auf Lambda bereitzustellen, stellen Sie sicher, dass Docker in Ihrer lokalen Umgebung ausgeführt wird, und führen Sie den folgenden Befehl aus.

    dotnet lambda deploy-function

    Hinter den Kulissen lädt die globale.NET-CLI ein AL2023 Docker-Image herunter und kompiliert Ihren Anwendungscode in einem laufenden Container. Die kompilierte Binärdatei wird zurück in Ihr lokales Dateisystem ausgegeben, bevor sie auf Lambda bereitgestellt wird.

  3. Testen Sie Ihre Funktion, indem Sie den folgenden Befehl ausführen. Ersetzen Sie <FUNCTION_NAME> durch den Namen, den Sie für Ihre Funktion im Bereitstellungsassistenten gewählt haben.

    dotnet lambda invoke-function <FUNCTION_NAME> --payload "hello world"

    Die Antwort der CLI enthält Leistungsdetails für den Kaltstart (Initialisierungsdauer) und die Gesamtlaufzeit für Ihren Funktionsaufruf.

  4. Führen Sie den folgenden Befehl aus, um die AWS Ressourcen zu löschen, die Sie mit den vorherigen Schritten erstellt haben. Ersetzen Sie <FUNCTION_NAME> durch den Namen, den Sie für Ihre Funktion im Bereitstellungsassistenten gewählt haben. Indem Sie AWS Ressourcen löschen, die Sie nicht mehr verwenden, verhindern Sie, dass Ihnen AWS-Konto unnötige Gebühren in Rechnung gestellt werden.

    dotnet lambda delete-function <FUNCTION_NAME>

Serialisierung

Um Funktionen mithilfe von nativem AOT für Lambda bereitzustellen, muss Ihr Funktionscode die quellgenerierte Serialisierung verwenden. Anstatt mithilfe der Laufzeitreflexion die Metadaten zu sammeln, die für den Zugriff auf Objekteigenschaften für die Serialisierung erforderlich sind, generieren Quellgeneratoren C#-Quelldateien, die beim Erstellen Ihrer Anwendung kompiliert werden. Um Ihren quellgenerierten Serializer korrekt zu konfigurieren, stellen Sie sicher, dass Sie alle Eingabe- und Ausgabeobjekte, die Ihre Funktion verwendet, sowie alle benutzerdefinierten Typen einbeziehen. Beispielsweise würde eine Lambda-Funktion, die Ereignisse von einer API-Gateway-REST-API empfängt und einen benutzerdefinierten Product-Typ zurückgibt, einen Serializer enthalten, der wie folgt definiert ist.

[JsonSerializable(typeof(APIGatewayProxyRequest))] [JsonSerializable(typeof(APIGatewayProxyResponse))] [JsonSerializable(typeof(Product))] public partial class CustomSerializer : JsonSerializerContext { }

Trimmen

Natives AOT kürzt Ihren Anwendungscode als Teil der Kompilierung, um sicherzustellen, dass die Binärdatei so klein wie möglich ist. .NET 8 for Lambda bietet im Vergleich zu früheren Versionen von.NET eine verbesserte Trimmunterstützung. Support wurde zu den Lambda-Laufzeitbibliotheken, AWS .NET SDK, .NET Lambda Annotations und .NET 8 selbst hinzugefügt.

Diese Verbesserungen bieten das Potenzial, Warnungen beim Trimmen während der Erstellung zu eliminieren, aber .NET wird niemals vollständig trimmsicher sein. Das bedeutet, dass Teile von Bibliotheken, auf die Ihre Funktion angewiesen ist, im Rahmen des Kompilierungsschritts entfernt werden können. Sie können dies verwalten, indem Sie es TrimmerRootAssemblies als Teil Ihrer .csproj Datei definieren, wie im folgenden Beispiel gezeigt.

<ItemGroup> <TrimmerRootAssembly Include="AWSSDK.Core" /> <TrimmerRootAssembly Include="AWSXRayRecorder.Core" /> <TrimmerRootAssembly Include="AWSXRayRecorder.Handlers.AwsSdk" /> <TrimmerRootAssembly Include="Amazon.Lambda.APIGatewayEvents" /> <TrimmerRootAssembly Include="bootstrap" /> <TrimmerRootAssembly Include="Shared" /> </ItemGroup>

Beachten Sie, dass das Problem TrimmerRootAssembly möglicherweise nicht behoben wird, wenn Sie eine Trimmwarnung erhalten, wenn Sie die Klasse hinzufügen, die die Warnung generiert. Eine Trim-Warnung weist darauf hin, dass die Klasse versucht, auf eine andere Klasse zuzugreifen, die erst zur Laufzeit ermittelt werden kann. Um Laufzeitfehler zu vermeiden, fügen Sie diese zweite Klasse hinzuTrimmerRootAssembly.

Weitere Informationen zur Verwaltung von Trimmwarnungen finden Sie in der Microsoft.NET-Dokumentation unter Einführung in Trimmwarnungen.

Fehlerbehebung

Fehler: Betriebssystemübergreifende native Kompilierung wird nicht unterstützt.

Ihre Version des globalen Amazon.Lambda.Tools-.NET-Core-Tools ist veraltet. Aktualisieren Sie auf die neueste Version und versuchen Sie es erneut.

Docker: das Image-Betriebssystem „Linux“ kann auf dieser Plattform nicht verwendet werden.

Docker ist auf Ihrem System für die Verwendung von Windows-Containern konfiguriert. Wechseln Sie zu Linux-Containern, um die native AOT-Entwicklungsumgebung auszuführen.

Weitere Informationen zu häufigen Fehlern finden Sie im AWS NativeAOT for .NET-Repository unter. GitHub