everythingpossible - Fotolia

F

Mit diesen Tricks lassen sich AWS Lambda-Probleme vermeiden

Viele Cloud-Operationen gehen reibungslos über die Bühne. Doch es gibt Fehler, welche die Arbeit vermasseln. Dazu gehören auch AWS Lambda-Funktionen.

Einige Fehler sind in der IT nur deshalb so verbreitet, weil es keine klare Lösung gibt, um sie zu verhindern. Eine Klammer weglassen, einen <div> -Tag in HTML nicht schließen oder Unicode in Python 2 unsachgemäß verwenden – das alles kann zu einer Fehlermeldung führen. Doch einige Fehler müssen einfach identifiziert werden, nachdem sie passiert sind.

In diesem Beitrag geht es um Fehler in AWS Lambda. Mit AWS Lambda können Sie bekanntlich Code für fast jede Anwendungsart oder jeden Backend-Service ausführen, ohne Server bereitzustellen und zu verwalten und ohne Administration. Sie laden Ihren Code einfach hoch und Lambda übernimmt alles, was zum Ausführen und Skalieren Ihres Codes erforderlich ist. Sie können Ihren Code so einrichten, dass er automatisch von anderen AWS-Services ausgelöst wird, oder ihn indirekt von einer beliebigen Web- oder Mobile-App aufrufen.

Leider ist der Umgang mit Fehlern und Fehlermeldungen in AWS Lambda alles andere als leicht. Zwar sind mit der Einführung von AWS Lambda die gleichen alten Fehler, die es in der IT schon immer gab, noch relevant. Allerdings kann es in AWS Lambda recht kompliziert werden, diese zu identifizieren. Wenn der Code lokal oder sogar in einer EC2-Instanz (Elastic Compute Cloud) ausgeführt wird, ist es einfach, sich eine Protokolldatei zu beschaffen und die Fehlermeldungen zu prüfen, um zu sehen, was schief gelaufen ist. Aber bei ereignisgesteuertem Computing gibt es keine physischen oder virtuellen Server, in die man sich einloggen kann. Deshalb kann es viel komplizierter sein, Lambda-Probleme zu erkennen.

Entwickler können die Gültigkeit des Codes und seine Syntax leicht mit einem JavaScript-Monitoring-Tool wie ESLint überprüfen. Allerdings kann das Aufspüren von Lambda-Problemen wie fehlende AWS IAM-Berechtigungen (Identity and Access Management) oder unerwarteter Input komplizierter sein.

Fehlende IAM-Berechtigungen

Probleme mit Berechtigungen können in der Regel nur schlecht aufgespürt werden. Jedes Mal, wenn ein Problem auftritt, scheint es am einfachsten zu sein, der IAM-Rolle, die die Lambda-Funktion ausführt, vollen Zugriff zu geben. Diesen Schritt sollte man nicht gehen.

Stattdessen sollten man den Code auf einer EC2-Instanz mit dieser Rolle laufen lassen und testen. Es ist eine gute Idee, die fehlgeschlagenen Berechtigungen für AWS mit einem Logging-Tool eines Drittanbieters oder in AWS CloudWatch-Protokollen aufzuzeichen und einen Benutzeralarm einzurichten.

Wenn zum Beispiel in Node.js ein Entwickler die aws-sdk verwendet, die automatisch in Lambda installiert ist, dann wird er Fehlermeldungen erhalten wie "[AccessDenied: Access Denied]". Stellen Sie sicher, dass die Fehlerreaktionen überprüft werden und zeichnen Sie diese für jeden AWS-API-Aufruf auf, der immer der erste Parameter in dem Callback ist, der Ihnen zur Verfügung steht.

Bei DynamoDB oder ähnliche Services sollten Sie nicht vergessen, Zugriff auf Tabellen und Indizes zu gewähren. Entwickler können den Zugriff auf alle Indizes in einer Tabelle über einen Platzhalter-Operator gewährleisten.

Prozess beendet, bevor die Anfrage abgeschlossen ist

Eines der schlimmsten Lambda-Probleme, mit dem ein Entwickler konfrontiert werden kann, ist die völlig nutzlose Nachricht, „Process exited before completing request" (Prozess vor Abschluss der Anfrage beendet). Sie bedeutet, dass die Code-Ausführung abgeschlossen ist, ohne dass irgendetwas aus dem "Context" Callback-Objekt aufgerufen wurde. Das könnte bedeuten, dass irgendetwas in dem Code einen Fehler verursachte oder es kann bedeuten, dass der Entwickler einfach vergessen hat, "context.done (err, msg)" nach Abschluss des Prozesses aufzurufen.

Bei asynchronem Code und multiplen Code-Pfaden kann dies besonders kompliziert sein. Man sollte sicherstellen, dass jede Art von Fehler abgefangen wird, die der Code verursacht hat, und diese angemessen protokolliert werden. Um Fehler anzuzeigen, kann "context.done (err)" verwendet werden, um diese zu wiederholen. Wenn es einen Fehler gibt, dieser aber nicht reproduziert werden kann – etwa ein Benutzerfehler, bei dem der Anwender versucht hat, ungültigen Input hochzuladen – sollte man "context.done (null, errResponse)" verwenden – sonst kann die Funktion den Aufruf erneut versuchen.

Es ist auch eine gute Idee, einen Log-Filter für das Muster „Process exited before completing request“ einzurichten und beim Auftreten einen Alarm zu senden. Wenn nur wenige von dieser Meldungen auftauchen, bedeutet dies wahrscheinlich, dass mit dem Code etwas falsch ist. Oder es kann bedeuten, dass der Code zu lange ausgeführt wird. Wenn der Code zu lange ausgeführt wird, sollte man den Timeout erhöhen. Dabei ist zu beachten: Der Timeout kann nur auf maximal fünf Minuten erhöht werden.

Gecachte Objekte aus einer vorherigen Ausführung

Zwischen Funktionsabläufen kann eine einzelne Code-Instanz übrig bleiben. Wenn Code außerhalb der "handler" -Funktion existiert, ist nicht garantiert, dass jede Lambda-Funktion ausgeführt wird. Zum Beispiel wird dieser Code nicht bei jeder Ausführung den aktuellen Zeitstempel zur Verfügung stellen:

var now = new Date();

  exports.handler = function(data, context){

   context.done(null, now.getTime());

  }

In diesem Code bekommt der Entwickler wahrscheinlich wiederholt denselben Zeitstempel, bis Lambda die Funktion bereinigt. Das kann unglaublich hilfreich sein, die Start-up-Zeit zu reduzieren, wenn man Ressourcen hat, die zwischen den Ausführungen im Cache gespeichert werden können. Allerdings sollte das vermieden werden, wenn jedes Mal beim Aufruf der Funktion eine saubere Ausführung erwartet wird.

Die richtige Methode, um diese Funktion zu schreiben, ist folgende:

exports.handler = function(data, context){

   var now = new Date();

   context.done(null, now.getTime());

  }

Lambda-Funktionen rufen Lambda-Funktionen auf

Es mag seltsam erscheinen, aber ein durchaus brauchbares Muster ist, mit Lambda-Funktionen andere Lambda-Funktionen aufzurufen. Der Trick besteht darin, die Funktion asynchron aufzurufen, ohne dass man auf eine Antwort von anderen Lambda-Funktionen warten muss.

Wenn man eine Funktion auslösen möchten, die asynchron arbeitet ohne auf die Antwort zu warten, sollte der InvocationType: "Event" verwendet werden:

lambda.invoke({

   InvocationType: 'Event',

   FunctionName: ‘doSomething',

   Payload: JSON.stringify(payload),

  }, function(e, resp){

   if(e){

    // Bedeutet wahrscheinlich dass wir keine Berechtigung haben

    console.error(e);

   }

   context.done(null, resp);

  });

Natürlich sollte sichergestellt sein, dass context.done () nicht aufgerufen wird, bis der gesamte Prozess abgeschlossen ist. Nach Abschluss des Prozesses wird der Code beendet.

Die richtige Versionen laufen lassen

Die Node.js-Versionen sind inzwischen bei 5.0.0, aber Lambda lässt eine Version vor Version 1.0.0 ausführen. Als das Node.js-Team mit dem "fork"-Team zusammenarbeitete, das IO.js entwickelte, arbeiteten sie hart an einem stabilen Release von Node.js. Zu diesem Zeitpunkt haben sie sich auch zur langfristigen Unterstützung von Node.js verpflichtet, aber Lambda ist immer noch veraltet.

Mittlerweile unterstützt Lambda Node.js 4.3. Dies ist eine Verbesserung, da es nativ Promises unterstützt. Doch diese Version ist ebenfalls über ein Jahr alt und eine neue Version von Lambda wird monatlich veröffentlicht. Es wird daher empfohlen, den Node Version Manager (NVM) zu installieren und den Code mit der bereitgestellten Version von Node.js in Lambda zu testen. NVM ermöglicht es Entwicklern, mehrere verschiedene Versionen von Node.js zu installieren und zwischen ihnen zu wechseln.

Was hat sich in den letzten Monaten verändert? Die versprochenen Features sind nun umgesetzt, der Stack zeichnet asynchronen Code auf und es wurden mehrere kleinere Performance- und Stabilitätsverbesserungen umgesetzt. Einige npm-Module funktionieren nicht bei älteren Node-Versionen, oder sie arbeiten auf andere Weise. Besonders das Networking scheint bei der Stabilität verbessert worden zu sein und kann Lambda-Probleme nun besser erkennen, wenn es APIs über HTTP und HTTPS verwendet.

Darüber hinaus sollte man Python Version 2.7 einsetzen. Wenn ein Entwickler mit Unicode arbeitet oder mit irgendetwas, das Python 3 Syntax oder Module verwendet, könnten Probleme entstehen.

Folgen Sie SearchEnterpriseSoftware.de auch auf Twitter, Google+ und Facebook!

Erfahren Sie mehr über Cloud Computing

- GOOGLE-ANZEIGEN

ComputerWeekly.de

Close