Es ist unbestritten, dass Amazon Web Services (AWS) die Beseititung von Fehlern in cloud-basierten Anwendungen vereinfacht. Der AWS-Service, den wir uns auf dieser Seite detailliert ansehen werden, ist AWS (Amazon) Lambda. Insbesondere liegt unser Fokus auf einer Herausforderung, mit der sich viele Entwickler konfrontiert sehen: das lokale Debuggen von Funktionen, die mit AWS bereitgestellt wurden. Hierbei werden wir uns auf Node.js konzentrieren.
Klären wir zunächst jedoch eine wichtige Frage:
Der Anspruch von AWS selbst ist es, dass Sie sich keine Gedanken um die Infrastruktur Ihres Projekts machen müssen. Anwendungen in der Cloud sollen direkt einsetzbar sein. Gleiches gilt für weitere Services von Amazon. Weitere wesentliche Vorteile sind die Skalierbarkeit und die geringen Kosten für die Nutzung der AWS-Rechenleistung.
Um zu beginnen, müssen Sie lediglich eine Lambda-Funktion schreiben und diese mit Events verknüpfen. Danach automatisiert Amazon die Funktion für jedes neue Event. Skalierung und Hochverfügbarkeit sind hierbei kein Thema mehr: Die Lambda-Funktion kann Tausende von Anfragen pro Stunde auf AWS (Amazon) ohne Aufwand oder ein Backend im herkömmlichen Sinne verarbeiten.
Hinsichtlich des Debugging-Prozesses für AWS (Amazon) Lambda-Funktionen stehen drei Methoden besonders im Vordergrund:
1. AWS Cloud Watch: die Standardmethode. Vorteilhaft ist insbesondere, dass AWS Cloud Watch kostenfrei genutzt werden kann. Nachteilig kann hingegen die unzureichende Performance sein. Ich persönlich habe über 40 Minuten mit dem Auslesen von Logs vergeudet. Auch wenn Cloud Watch kostenlos ist, sollten Sie den Zeitaufwand und die damit zusammenhängenden Kosten dennoch berücksichtigen.
2. Logging bereitgestellter Lambda-Funktionen: Dies kann mithilfe anderer AWS-Services wie Kinesis erfolgen. Für Entwickler mag dieser Prozess zunächst schneller erscheinen. Die Notwendigkeit, Tools manuell zu erstellen, kann jedoch einen deutlich höheren Zeitaufwand verursachen, als zu vermuten ist. Dies hat ebenso einen gewissen Einfluss auf das Budget wie die Nutzung der zusätzlichen Amazon-Infrastruktur.
3. Offline-Debugging: Diese Option kommt bei Standard-Entwicklungsprozessen infrage und ermöglicht es, lokal zu arbeiten.
AWS hat spezielle Werkzeuge entwickelt, die das Debuggen von Lambda-Funktionen unterstützen:
– AWS Serverless Application Model (SAM/serverloses Anwendungsmodell)
– AWS SAM CLI
AWS SAM (4.323 GitHub-Sterne) ergänzt die AWS CloudFormation um eine vereinfachte Methode zur Definition der Gateway-APIs, AWS (Amazon) Lambda-Funktionen und Amazon DynamoDB-Tabellen für serverlose Anwendungen. Zusätzlich besteht die Möglichkeit, lokal (oder offline) mit AWS SAM CLI zu debuggen.
AWS SAM CLI (3.682 GitHub-Sterne) kann Code in einem Docker-Container ausführen (Emulation einer Lambda-Laufzeitumgebung auf Amazon-Servern), Request-Daten in API-Gateway-Events umwandeln und Funktionen mit diesem Event aufrufen.
AWS SAM CLI ermöglicht es Ihnen, Ihren Code in einer Umgebung auszuführen, welche die tatsächliche AWS (Amazon) Lambda-Umgebung nachbildet. Das bedeutet, dass Sie Breakpoints innerhalb des Codes setzen und davon ausgehen können, dass der Debug-Output mit der bereitgestellten Funktion übereinstimmt. Ist die Funktion, die auf AWS (Amazon) Lambda bereitgestellt wird, fehlerhaft, können Sie sicher sein, dass der lokale Aufruf zum gleichen Ergebnis führt.
All diese Tools und Methoden haben ihre Stärken. Dem gegenüber existieren jedoch auch Schwächen, die es zu berücksichtigen gilt:
– Geringe Flexibilität und Leistungsfähigkeit. Es existieren keine Plugins. Sie können daher lediglich Merge Requests zu Hauptprojekten durchführen.
– AWS SAM wird von Golang entwickelt, während AWS SAM CLI von Python stammt. Hierdurch besteht die Notwendigkeit, Verbesserungen oder Funktionen in diesen Sprachen zu entwickeln.
– Es existieren zahlreiche Quellen für Lambda-Funktionsaufrufe. Nutzt Ihr Projekt mehr als Lambda und API-Gateway, so müssen diese emuliert werden. Die Offline-Anwendung der AWS-Services stellt eine Herausforderung dar. Für jeden Service muss eine Event-Datei erstellt werden. Die Funktionen müssen mit diesem Event manuell über ein AWS-SAM-CLI-Modul aufgerufen werden.
Im Kontext von Node.js ist „Serverless Offline“ das beliebteste Modul zum lokalen Debuggen von Lambda AWS. Es handelt sich hierbei um ein Plugin für „Serverless Framework“ (26.804 GitHub-Sterne). Serverless Framework ist wiederum ein JS-Tool und ein Wrapper auf AWS CloudFront. Es besitzt eine gewisse Ähnlichkeit zu AWS SAM, bietet jedoch eine klare Syntax und eine Reihe anderer zusätzlicher Funktionen, die nicht in „SAM“ enthalten sind. Zudem sind eine Reihe von Plugins verfügbar, die die Logik verschiedener AWS (Amazon) Services (S3, SNS, SQS und andere) lokal emulieren. Für „Serverless“ existieren auch Plugins für andere Programmiersprachen (z. B. Python, Swift, PHP und Golang).
Lambda auf AWS (Amazon) debuggen: ein simples Beispiel
Um lokale Emulationen von AWS Lambda-Funktionen aufzurufen und zu debuggen, müssen wir zunächst zwei NPM-Pakete installieren: „Serverless“ und „Serverless-offline“. Denken Sie daran, dass diese beiden Pakete aufgrund der Anzahl der Trigger der Lambda-Funktion (S3, SQS, API Gateway und andere Services sowie Verbindungen zwischen diesen Services und Ihrem Computer durch AWS CLI) nicht für ein reales Projekt ausreichen.
Wir benötigen auf unserer Maschine daher eine Verbindung zwischen AWS und Serverless. Sie müssen hierfür andere Plugins und Funktionalitäten von Serverless installieren und anwenden. Für das Lambda-Debugging genügt jedoch eine einfache Funktion, sofern das API-Gateway in Form eines Triggers (eine grundlegende Ressource, von der die meisten Requests ausgehen) verwendet wird.
Wir werden im Folgenden nicht jede einzelne Zeile der Datei „serverless.yml“ erläutern. Antworten auf weitergehende Fragen finden Sie im Rahmen einer kleinen Online-Recherche sehr schnell selbst. Zudem werden „Serverless Framework“ und „Serverless Offline“ durch eine hervorragende Dokumentation gestützt.
Zur Veranschaulichung führen wir die folgenden Schritte durch:
1. Solange unsere Laufzeit-Option der von Node.js 8.10 entspricht, ist die Funktionsfähigkeit auf Ihrer Maschinen gegeben. Wir müssen zudem die Node.js-Version 8.0.0 oder höher verwenden (8.10 ist optimal). Überprüfen Sie also Ihre Version mit folgendem Befehl:
$ node -v
Ist das Ergebnis niedriger als “v8.0.0”, installieren Sie die erforderliche Version. Diese ist hier verfügbar.
2. Unser einfaches Projekt und seine Abhängigkeiten sind enthalten:
$ mkdir debug-lambda-local && cd debug-lambda-local && npm init -f && npm i -D serverless serverless-offline
3. Erstellen Sie die Dateien „serverless.yml“ und „lambda-foo.js“:
$ touch serverless.yml lambda-foo.js
4. Fügen Sie der Datei „serverless.yml“ den untenstehenden Code hinzu, um das Serverless Framework und das Serverless-Offline-Plugin zu konfigurieren. Letzteres emuliert das Verhalten des API Gateways (Proxy Servers):
serverless.yml
plugins: serverless-offline provider: name: aws runtime: nodejs8.10 stage: dev region: us-east-1 functions: getresponse: handler: lambda-foo.getResponse events: - http: path: getresponse method: GET custom: serverless-offline: port: 1221
5. Als Nächstes fügen Sie einen einfachen Code mit unserer Lambda-Funktion in die Datei „lambda-foo.js“. Dieser reagiert auf den Aufruf des API-Gateways. „console.log“ kann an einer beliebigen Stelle der Datei platziert werden:
lambda-foo.js
const TIMEOUT = 1000; const getResult = () => new Promise((resolve) => setTimeout(() => resolve(`Resolved after ${TIMEOUT} ms`), TIMEOUT)); exports.getResponse = async (event, context) => { return { statusCode: 200, body: JSON.stringify({ result: await getResult(), }), } }
6. Bei Bedarf können Sie diese Datei auch durch andere Handler für API-Gateway-Anfragen ersetzen.
7. Starten Sie Ihre AWS-Emulation im Watch-Modus:
$ node_modules/.bin/serverless offline start
So wird sich der Emulationsprozess des API-Gateways auf localhost:1221 darstellen.
8. Es folgt der letzte Schritt. Rufen Sie den GET localhost:1221/getresponse auf und betrachten Sie den Debug-Output der Funktion „getResponse“. Dies erfolgt im Terminalfenster, in dem wir Serverless gestartet haben.
Sie werden schnell feststellen, dass das Serverless Framework einfach zu handhaben ist. Den wesentlichen Nachteil dürfen wir jedoch nicht vergessen. Die Breakpoints Ihres Codes sind kein zuverlässiger Anhaltspunkt, da sie nicht den gleichen Output aufweisen wie die bereitgestellte Version. Die Laufzeitumgebung ist zwar ähnlich, jedoch nicht vollständig identisch.
Zusammenfassung
1. Lambda (Amazon) AWS-Funktionen arbeiten in einer isolierten Umgebung. Hierdurch gestaltet sich das Debugging zunehmend komplexer. Um dies auszugleichen, kann die Funktion bis zur Bereitstellung lokal und nach der Bereitstellung in der Cloud ausgeführt werden.
2. Es ist wichtig, klar zwischen lokalen Tools und Kommunikationsmethoden mit Cloud-Post-Deployment zu unterscheiden.
3. Zum Überwachen und Debuggen Ihres Codes nutzen Sie in der Entwicklungsphase Serverless Offline oder Serverless Application Model.
4. Sowohl Serverless als auch SAM ermöglichen ein manuelles Testen der Funktionalität. Aufwände für das Deployment und weitere Requests an die AWS (Amazon) Cloud entstehen hierbei nicht.