Effiziente Backend-Entwicklung mit Serverless-Technologien
Mit Serverless Technologien lassen sich robuste und skalierbare Backends realisieren, die extrem kostengünstig betrieben werden können. Wir bei der innFactory setzen seit 2022 verstärkt auf Backends, die komplett als Serverless Architektur umgesetzt werden. Was das genau ist, und wie wir die Technologien umsetzen, wollen wir in diesem Artikel erläutern.
Serverless Functions
Serverless Functions sind das zentrale Element einer Serverless-Architektur. Sie stellen eine Möglichkeit dar, Code auszuführen, ohne dass Entwickler sich um die zugrunde liegende Infrastruktur oder die Server kümmern müssen. Der Begriff “serverless” bedeutet hierbei nicht, dass tatsächlich keine Server verwendet werden, sondern vielmehr, dass Entwickler sich nicht mehr um die Verwaltung und Skalierung dieser Server kümmern müssen.
Hier sind einige Schlüsselmerkmale von Serverless Functions:
- Eventgetriebene Ausführung: Serverless Functions werden in der Regel aufgrund von Ereignissen oder Anfragen aktiviert. Beispiele für Ereignisse sind HTTP-Anfragen über API-Gateways, das Hinzufügen einer Datei in einem Speicherdienst oder das Auslösen einer Zeitplanung (CRON-Jobs).
- Automatische Skalierung: Die Serverless-Plattform kümmert sich automatisch um die Skalierung der Funktionen basierend auf der Anzahl der eingehenden Anfragen oder Events. Dies ermöglicht es, mit stark variierenden Workloads umzugehen, ohne manuell Ressourcen anpassen zu müssen.
- Abrechnung nach Verbrauch: Entwickler zahlen nur für die tatsächlich verbrauchten Ressourcen und die Ausführungszeit ihrer Funktionen. Wenn eine Funktion nicht aktiv ist, fallen auch keine Kosten an.
- Isolation und Sicherheit: Jede Funktion wird in einer isolierten Umgebung ausgeführt, wodurch Sicherheitsrisiken minimiert werden. Funktionen haben normalerweise keinen direkten Zugriff auf die zugrunde liegende Infrastruktur.
- Vielfältige Anwendungsfälle: Serverless Functions können in einer Vielzahl von Anwendungsfällen eingesetzt werden. Konkrete Beispiele für welche Aufgaben wir Serverless Functions im Einsatz haben (auch in „klassischen“ Cloud Projekten):
- PDF Generierung Baufinanzierungskonzept (Laura AI, VR-Bank)
- Automatische Rechnungserstellung (intern, Clockodo + Easybill)
- Speichern der Formulardaten von smartcity-rosenheim.de
- CSV-Export von WLAN-Qualität in Filialen (Rossmann)
- Import von Hotel-Stammdaten (Familotel)
Serverless Functions bieten alle großen Cloud Provider an. Bei Google heißen diese „Cloud Functions“ bei AWS „Lambda Functions“ und bei Azure „Azure Functions“. Als Programmiersprache setzen wir meist auf Typescript/Node.js für Serverless Functions. Die Cloudprovider bieten aber mittlerweile sehr viele Alternativen an. Für sehr rechenintensive Anwendung beispielsweise Go oder Rust. Aber auch altbewährte Größen wie Java oder C# sind neben der aufsteigenden Sprache Python am Start.
Komplexität bei einer großen Menge an Serverless Functions
Während die Verwendung einzelner Functions in Projekten meist unproblematisch ist, da diese nach unserer Erfahrung immer „Sonderaufgaben“ übernehmen, die autark und recht abgekapselt vom Rest liefen, kann ein ganzes Backend auf Basis von Serverless Functions verschiedene Probleme mit sich bringen. Wir sehen später, wie diese Probleme mit Hilfe von SST gelöst werden können:
- Komplexität der Architektur: Mit der Zunahme der Anzahl von Serverless Functions kann die Gesamtarchitektur sehr unübersichtlich werden.
- Deployment: Wenn eine Function deployed wird, wird sie in der Regel gelöscht und wieder neu erstellt, das kostet sehr viel Zeit bei vielen Functions. Auch der Überblick, ob eine Function deployed ist und wie aktuell sie ist, ist bei mehreren Umgebungen sehr unübersichtlich.
- Andere Cloud Ressourcen: Functions greifen oft auf andere Cloud Ressourcen zu, wie z.B. Datenbanken. Hierbei brauch ein Function eine Berechtigung, die explizit nur die benötigten Ressourcen freigibt. Zudem müssen natürlich auch die anderen Ressourcen existieren und entsprechen konfiguriert sein.
- Cold Starts: Serverless Functions können beim ersten Aufruf nach längerer Zeit ein paar Sekunden brauchen, bis sie wirklich geladen und ausgeführt werden.
Infrastruktur beschreiben mit SST (Serverless Stack Toolkit) oder Serverless-Framework
Die Lösung für die oben genannten Probleme bieten Tools wie SST oder das Serverless-Framework.
Mit diesen Tools kann die Architektur der Functions mit Typescript (SST) oder YAML (Serverless-Framework) beschrieben werden. Auch um das Deployment kümmern sich diese Tools. So werden beispielsweise über nur einen Command alle Functions deployed und zudem darauf geachtet, dass nur jene geupdatet werden, die sich auch verändert haben. Die Zugriffsberechtigungen lassen sich direkt in der Infrastrukturbeschreibung definieren und auch Cold Starts können durch das Konfigurieren von „Warmhalten“ der Functions vermieden werden.
SST vs. Serverless-Framework
Grundsätzlich hat SST noch mehr den Fokus auf die komplette Infrastrukturbeschreibung, während das Serverless-Framework den Fokus auf das Deployment von Serverless Functions hat. Beides der Tools würde sich aber für die Umsetzung von Serverless Backends eignen. Hier noch weitere Punkte in denen sich die Werkzeuge unterscheiden:
Vorteile SST:
- Mit SST beschreibt man die komplette Cloud Infrastruktur inkl. Frontend Integration -> alles in einem Projekt
- SST bietet eine extrem gute Developer Experience: Zum Testen und Debugging läuft die Geschäftslogik der Function lokal auf der eigenen Maschine. Über einen Websocket wird zur deployten Function kommuniziert und somit auch Zugriffe zur restlichen Infrastruktur ermöglicht. Das Debugging ist jedoch lokal, was schneller und einfachere Fehleranalysen ermöglicht und auch Änderungen instant miteinfließen lässt (Live-Reloading).
Vorteile Serverless Framework:
- Serverless hat mehr Programmiersprachen für Functions zur Auswahl (Node.js, Python, Java, Go, C#, Ruby Swift, Kotlin, PHP, Scala, F#)
- Serverless ist unabhängig vom Cloud Provider, während SST nur mit AWS kann
SST vs. CDK
Wer viel mit AWS zu tun hat, fragt sich jetzt, was der Unterschied zum Cloud Development Kit (CDK) von AWS ist. Darum listen wir hier kurz die Entscheidenden Punkte auf:
- Baut auf CDK auf
- CDK Code kann frei ergänzt werden falls nötig
- Einfaches Deployment verschiedener Umgebungen
- Umgebung je Entwickler
- Testing von Infrastruktur und Geschäftslogik
- Datenbank Migrationen
- Typesafe und Autocomplete dank Typescript
- Automatisierung des Frontenddeployments (Erstellung von S3 Bucket, CloudFront Distribution etc)
Fazit
Wir haben nun schon mehrere Projekte mit SST umgesetzt. Der größte Mehrwert bei Serverless-Architekturen entsteht für den Kunden in Form von den sehr geringen Betriebskosten. Aber auch die Umsetzung und Wartung ist dank SST fast gleichauf wie zur klassischen Microservice-Architektur, die wir fast immer mit Scala und Akka umsetzen. Nach unserer Erfahrung nach, eignet sich die Serverless-Architektur am besten für Anwendungen, die überwiegen CRUD-Operationen beinhalten, während wir für speziellere Use Cases (z.B. der Betrieb von Machine Learning oder andere rechenintensive Backends) weiterhin fest auf Scala, Kubernetes und Co. setzen.