Definieren Sie den Lambda-Funktionshandler in Rust - 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.

Definieren Sie den Lambda-Funktionshandler in Rust

Anmerkung

Der Rust-Laufzeit-Client ist ein experimentelles Paket. Er kann sich ändern und ist nur zu Evaluierungszwecken gedacht.

Der Lambda-Funktionshandler ist die Methode in Ihrem Funktionscode, die Ereignisse verarbeitet. Wenn Ihre Funktion aufgerufen wird, führt Lambda die Handler-Methode aus. Ihre Funktion wird so lange ausgeführt, bis der Handler eine Antwort zurückgibt, beendet wird oder ein Timeout auftritt.

Grundlagen des Rust-Handlers

Schreiben Sie Ihren Lambda-Funktionscode als ausführbare Rust-Datei. Implementieren Sie den Handler-Funktionscode und eine Hauptfunktion und fügen Sie Folgendes hinzu:

Beispiel — Rust-Handler, der JSON Ereignisse verarbeitet

Das folgende Beispiel verwendet die Kiste serde_json, um grundlegende Ereignisse zu verarbeiten: JSON

use lambda_runtime::{service_fn, LambdaEvent, Error}; use serde_json::{json, Value}; async fn handler(event: LambdaEvent<Value>) -> Result<Value, Error> { let payload = event.payload; let first_name = payload["firstName"].as_str().unwrap_or("world"); Ok(json!({ "message": format!("Hello, {first_name}!") })) } #[tokio::main] async fn main() -> Result<(), Error> { lambda_runtime::run(service_fn(handler)).await }

Beachten Sie Folgendes:

  • use: Importiert die Bibliotheken, die Ihre Lambda-Funktion benötigt.

  • async fn main: Der Eintrittspunkt, von dem aus der Lambda-Funktionscode ausgeführt wird. Der Rust-Laufzeit-Client verwendet Tokio als asynchrone Laufzeit, daher müssen Sie die Hauptfunktion mit #[tokio::main] annotieren.

  • async fn handler(event: LambdaEvent<Value>) -> Result<Value,Error>: Dies ist die Lambda-Handler-Signatur. Sie enthält den Code, der ausgeführt wird, wenn die Funktion aufgerufen wird.

    • LambdaEvent<Value>: Dies ist ein generischer Typ, der das von der Lambda-Laufzeit empfangene Ereignis sowie den Lambda-Funktionskontext beschreibt.

    • Result<Value, Error>: Die Funktion gibt einen Result-Typ zurück. Wenn die Funktion erfolgreich ist, ist das Ergebnis ein Wert. JSON Wenn die Funktion nicht erfolgreich ist, ist das Ergebnis ein Fehler.

Geteilten Zustand verwenden

Sie können geteilte Variablen deklarieren, die unabhängig vom Handler-Code Ihrer Lambda-Funktion sind. Diese Variablen können Ihnen helfen, Zustandsinformationen während des Init-Phase zu laden, bevor Ihre Funktion Ereignisse empfängt.

Beispiel – Verwenden Sie den Amazon-S3-Client für mehrere Funktions-Instances

Beachten Sie Folgendes:

  • use aws_sdk_s3::Client: In diesem Beispiel müssen Sie aws-sdk-s3 = "0.26.0" zur Liste der Abhängigkeiten in Ihrer Cargo.toml-Datei hinzufügen.

  • aws_config::from_env: In diesem Beispiel müssen Sie aws-config = "0.55.1" zur Liste der Abhängigkeiten in Ihrer Cargo.toml-Datei hinzufügen.

use aws_sdk_s3::Client; use lambda_runtime::{service_fn, Error, LambdaEvent}; use serde::{Deserialize, Serialize}; #[derive(Deserialize)] struct Request { bucket: String, } #[derive(Serialize)] struct Response { keys: Vec<String>, } async fn handler(client: &Client, event: LambdaEvent<Request>) -> Result<Response, Error> { let bucket = event.payload.bucket; let objects = client.list_objects_v2().bucket(bucket).send().await?; let keys = objects .contents() .map(|s| s.iter().flat_map(|o| o.key().map(String::from)).collect()) .unwrap_or_default(); Ok(Response { keys }) } #[tokio::main] async fn main() -> Result<(), Error> { let shared_config = aws_config::from_env().load().await; let client = Client::new(&shared_config); let shared_client = &client; lambda_runtime::run(service_fn(move |event: LambdaEvent<Request>| async move { handler(&shared_client, event).await })) .await }

Bewährte Codepraktiken für Rust-Lambda-Funktionen

Halten Sie sich an die Richtlinien in der folgenden Liste, um beim Erstellen Ihrer Lambda-Funktionen die besten Codierungspraktiken anzuwenden:

  • Trennen Sie den Lambda-Handler von Ihrer Core-Logik. Auf diese Weise können Sie eine Funktion zur besseren Prüfbarkeit von Einheiten schaffen.

  • Minimieren Sie die Komplexität Ihrer Abhängigkeiten. Ziehen Sie einfachere Frameworks vor, die sich schnell beim Start der Ausführungsumgebung laden lassen.

  • Minimieren Sie die Größe Ihres Bereitstellungspakets auf die für die Laufzeit erforderliche Größe. Dadurch verkürzt sich die Zeit, die für das Herunterladen und Entpacken Ihres Bereitstellungspakets vor dem Aufruf benötigt wird.

  • Nutzen Sie die Wiederverwendung der Ausführungsumgebung zur Verbesserung Ihrer Funktion. Initialisieren Sie SDK Clients und Datenbankverbindungen außerhalb des Funktionshandlers und speichern Sie statische Assets lokal im /tmp Verzeichnis. Nachfolgende Aufrufe, die von derselben Instance Ihrer Funktion verarbeitet werden, können diese Ressourcen wiederverwenden. Dies spart Kosten durch Reduzierung der Funktionslaufzeit.

    Um potenzielle Datenlecks über Aufrufe hinweg zu vermeiden, verwenden Sie die Ausführungsumgebung nicht, um Benutzerdaten, Ereignisse oder andere Informationen mit Sicherheitsauswirkungen zu speichern. Wenn Ihre Funktion auf einem veränderbaren Zustand beruht, der nicht im Speicher innerhalb des Handlers gespeichert werden kann, sollten Sie für jeden Benutzer eine separate Funktion oder separate Versionen einer Funktion erstellen.

  • Verwenden Sie eine Keep-Alive-Direktive, um dauerhafte Verbindungen zu pflegen. Lambda bereinigt Leerlaufverbindungen im Laufe der Zeit. Der Versuch, eine Leerlaufverbindung beim Aufruf einer Funktion wiederzuverwenden, führt zu einem Verbindungsfehler. Um Ihre persistente Verbindung aufrechtzuerhalten, verwenden Sie die Keep-Alive-Direktive, die Ihrer Laufzeit zugeordnet ist. Ein Beispiel finden Sie unter Wiederverwenden von Verbindungen mit Keep-Alive in Node.js.

  • Verwenden Sie Umgebungsvariablen um Betriebsparameter an Ihre Funktion zu übergeben. Wenn Sie z. B. Daten in einen Amazon-S3-Bucket schreiben, anstatt den Bucket-Namen, in den Sie schreiben, hartzucodieren, konfigurieren Sie den Bucket-Namen als Umgebungsvariable.

  • Vermeiden Sie rekursive Aufrufe in Ihrer Lambda-Funktion, bei denen sich die Funktion selbst aufruft oder einen Prozess initiiert, der die Funktion möglicherweise erneut aufruft. Dies kann zu unvorhergesehenen Mengen an Funktionsaufrufen führen und höhere Kosten zur Folge haben. Wenn Sie eine unbeabsichtigte Anzahl von Aufrufen sehen, setzen Sie die für die Funktion reservierte Parallelität auf 0 sofort, um alle Aufrufe der Funktion zu drosseln, während Sie den Code aktualisieren.

  • Verwenden Sie APIs in Ihrem Lambda-Funktionscode nicht undokumentiert, nicht öffentlich. Für AWS Lambda verwaltete Laufzeiten führt Lambda regelmäßig Sicherheits- und Funktionsupdates für interne Lambda-Laufzeiten durch. APIs Diese internen API Updates können abwärtsinkompatibel sein, was zu unbeabsichtigten Folgen wie Aufruffehlern führen kann, wenn Ihre Funktion von diesen nicht öffentlichen Daten abhängig ist. APIs Eine Liste der öffentlich verfügbaren Dateien finden Sie in der API Referenz. APIs

  • Schreiben Sie idempotenten Code. Das Schreiben idempotenter Code für Ihre Funktionen stellt sicher, dass doppelte Ereignisse auf die gleiche Weise behandelt werden. Ihr Code sollte Ereignisse ordnungsgemäß validieren und doppelte Ereignisse ordnungsgemäß behandeln. Weitere Informationen finden Sie unter Wie mache ich meine Lambda-Funktion idempotent?.