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

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 Go-Handlers

Eine Lambda-Funktion in Go wird als ausführbare Go-Datei erstellt. In Ihren Lambda-Funktionscode müssen Sie das Paket github.com/aws/ aws-lambda-go /lambda aufnehmen, das das Lambda-Programmiermodell für Go implementiert. Darüber hinaus müssen Sie Handler-Funktionscode und eine main()-Funktion implementieren.

Beispiel Go-Lambda-Funktion
package main import ( "context" "fmt" "github.com/aws/aws-lambda-go/lambda" ) type MyEvent struct { Name string `json:"name"` } func HandleRequest(ctx context.Context, event *MyEvent) (*string, error) { if event == nil { return nil, fmt.Errorf("received nil event") } message := fmt.Sprintf("Hello %s!", event.Name) return &message, nil } func main() { lambda.Start(HandleRequest) }

Hier ist eine Beispieleingabe für diese Funktion:

{ "name": "Jane" }

Beachten Sie Folgendes:

  • Paket „main“: In Go muss das Paket mit func main() stets den Namen main haben.

  • Importieren: Damit können Sie die Bibliotheken einschließen, die Ihre Lambda-Funktion erfordert. In diesem Fall sind dies:

  • func HandleRequest (ctx context.Context, event *MyEvent) (*string, error): Dies ist die Signatur Ihres Lambda-Handlers. Es ist der Einstiegspunkt für Ihre Lambda-Funktion und enthält die Logik, die ausgeführt wird, wenn Ihre Funktion aufgerufen wird. Darüber hinaus geben die enthalten Parameter Folgendes an:

    • ctx context.Context: Stellt Laufzeitinformationen für Ihren Lambda-Funktionsaufruf bereit. ctx ist die Variable, die Sie deklarieren, um die verfügbaren Informationen über Verwenden des Lambda-Kontextobjekts zum Abrufen von Go-Funktionsinformationen zu nutzen.

    • event * MyEvent: Dies ist ein Parameter mit dem Namen, auf den verweist. event MyEvent Es stellt die Eingabe für die Lambda-Funktion dar.

    • *string, error: Der Handler gibt zwei Werte zurück. Der erste ist ein Zeiger auf eine Zeichenfolge, die das Ergebnis der Lambda-Funktion enthält. Der zweite ist ein Fehlertyp, der nil ist, wenn kein Fehler vorliegt, und der standardmäßige Fehlerinformationen enthält, falls etwas schief geht.

    • return &message, nil: Gibt zwei Werte zurück. Der erste ist ein Zeiger auf eine Zeichenfolgennachricht, bei der es sich um eine Begrüßung handelt, die anhand des Name-Felds aus dem Eingabeereignis erstellt wurde. Der zweite Wert, nil, gibt an, dass bei der Funktion keine Fehler aufgetreten sind.

  • func main(): Der Eintrittspunkt, von dem aus Ihr Lambda-Funktionscode ausgeführt wird. Diese Information ist erforderlich.

    Indem Sie lambda.Start(HandleRequest) zwischen den func main(){}-Code-Klammern hinzufügen, wird Ihre Lambda-Funktion ausgeführt. Laut den Standards der Go-Sprache muss sich die offene Klammer { direkt am Ende der main-Funktionssignatur befinden.

Benennung

provided.al2 and provided.al2023 Laufzeiten

Bei Go-Funktionen, die die Laufzeit provided.al2 oder provided.al2023 in einem ZIP-Bereitstellungspaket verwenden, muss die ausführbare Datei, die Ihren Funktionscode enthält, bootstrap heißen. Wenn Sie eine Funktion über eine ZIP-Datei bereitstellen, muss sich die bootstrap-Datei im Stammverzeichnis der ZIP-Datei befinden. Bei Go-Funktionen, die die Laufzeit provided.al2 oder provided.al2023 in einem Container-Image verwenden, kann die ausführbare Datei einen beliebigen Namen haben.

Für den Handler kann ein beliebiger Name verwendet werden. Sie können die Umgebungsvariable _HANDLER verwenden, um in Ihrem Code auf den Handler-Wert zu verweisen.

Laufzeit „go1.x“

Bei Go-Funktionen, die die Laufzeit go1.x verwenden, können sich die ausführbare Datei und der Handler einen beliebigen Namen teilen. Wenn Sie beispielsweise den Wert des Handlers auf Handler setzen, ruft Lambda die Funktion main() in der ausführbaren Datei Handler auf.

Um den Namen des Funktionshandlers in der Lambda-Konsole zu ändern, wählen Sie im Bereich Laufzeiteinstellungen die Option Bearbeiten.

Lambda-Funktions-Handler mit strukturierten Typen

Im obigen Beispiel handelte es sich beim Eingabetyp um eine einfache Zeichenfolge. Sie können jedoch auch strukturierte Ereignisse an Ihren Funktions-Handler übergeben:

package main import ( "fmt" "github.com/aws/aws-lambda-go/lambda" ) type MyEvent struct { Name string `json:"What is your name?"` Age int `json:"How old are you?"` } type MyResponse struct { Message string `json:"Answer"` } func HandleLambdaEvent(event *MyEvent) (*MyResponse, error) { if event == nil { return nil, fmt.Errorf("received nil event") } return &MyResponse{Message: fmt.Sprintf("%s is %d years old!", event.Name, event.Age)}, nil } func main() { lambda.Start(HandleLambdaEvent) }

Hier ist eine Beispieleingabe für diese Funktion:

{ "What is your name?": "Jim", "How old are you?": 33 }

Die Antwort schaut wie folgt aus:

{ "Answer": "Jim is 33 years old!" }

Um exportiert werden, müssen Feldnamen in der Ereignisstruktur großgeschrieben werden. Weitere Informationen zum Umgang mit Ereignissen aus AWS Ereignisquellen finden Sie unter aws-lambda-go/events.

Gültige Handler-Signaturen

Sie haben bei der Erstellung eines Lambda-Funktions-Handlers in Go mehrere Möglichkeiten. Allerdings müssen die folgenden Regeln beachten:

  • Der Handler muss eine Funktion sein.

  • Der Handler kann zwischen 0 und 2 Argumente aufnehmen. Bei zwei Argumenten muss das erste Argument implementiere context.Context.

  • Der Handler kann zwischen 0 und 2 Argumente zurückgeben. Bei einem einzigen Rückgabewert muss er implementiere error. Bei zwei Rückgabewerten muss der zweite Wert implementiere error.

Im Folgenden werden gültige Handler-Signaturen aufgeführt. TIn und TOut stellen Typen dar, die mit der Standardbibliothek encoding/json kompatibel sind. Weitere Informationen zur Deserialisierung dieser Typen finden Sie unter func Unmarshal.

  • func ()
  • func () error
  • func (TIn) error
  • func () (TOut, error)
  • func (context.Context) error
  • func (context.Context, TIn) error
  • func (context.Context) (TOut, error)
  • func (context.Context, TIn) (TOut, error)

Verwenden des globalen Zustands

Sie können globale Variablen deklarieren und ändern, die vom Handler-Code Ihrer Lambda-Funktion unabhängig sind. Darüber hinaus deklariert Ihr Handler möglicherweise eine init-Funktion, die ausgeführt wird, wenn Ihr Handler geladen wird. Dies verhält sich genauso AWS Lambda wie in Standard-Go-Programmen. Eine einzelne Instance Ihrer Lambda-Funktion behandelt nie mehrere Ereignisse gleichzeitig.

Beispiel Go-Funktion mit globalen Variablen
Anmerkung

Dieser Code verwendet die AWS SDK for Go V2. Weitere Informationen finden Sie unter Erste Schritte mit der AWS SDK for Go V2.

package main import ( "context" "github.com/aws/aws-lambda-go/lambda" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/s3" "github.com/aws/aws-sdk-go-v2/service/s3/types" "log" ) var invokeCount int var myObjects []types.Object func init() { // Load the SDK configuration cfg, err := config.LoadDefaultConfig(context.TODO()) if err != nil { log.Fatalf("Unable to load SDK config: %v", err) } // Initialize an S3 client svc := s3.NewFromConfig(cfg) // Define the bucket name as a variable so we can take its address bucketName := "amzn-s3-demo-bucket" input := &s3.ListObjectsV2Input{ Bucket: &bucketName, } // List objects in the bucket result, err := svc.ListObjectsV2(context.TODO(), input) if err != nil { log.Fatalf("Failed to list objects: %v", err) } myObjects = result.Contents } func LambdaHandler(ctx context.Context) (int, error) { invokeCount++ for i, obj := range myObjects { log.Printf("object[%d] size: %d key: %s", i, obj.Size, *obj.Key) } return invokeCount, nil } func main() { lambda.Start(LambdaHandler) }

Bewährte Codemethoden für Go 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?.