Kapitel 4. Die Kräfte hinter Serverless

Diese Arbeit wurde mithilfe von KI übersetzt. Wir freuen uns über dein Feedback und deine Kommentare: translation-feedback@oreilly.com

In diesem Kapitel geht es vor allem darum, die Zutaten zu verstehen, die Serverless heute und in Zukunft erfolgreich machen. (Ich habe keine Kristallkugel, aber die strukturellen Vorteile von Serverless werden sich wahrscheinlich fortsetzen, bis jemand einen noch besseren Weg findet, Entwicklern bei der Erstellung skalierbarer Anwendungen zu helfen).

Drei Hauptkräfte haben dazu beigetragen, dass Serverless ein beliebtes Paradigma geworden ist. Heutzutage haben viele Unternehmen immer noch große, geschäftskritische Monolithen - selbst Mainframe-Anwendungen sind in vielen Branchen von entscheidender Bedeutung! In den nächsten 20 Jahren erwarte ich, dass Serverless bei vielen dieser bestehenden Anwendungen eine größere Rolle spielen und neben den bestehenden Monolithen und Mainframes bestehen wird. Das ist großartig - die meisten Technologien ersetzen ihre Vorgänger nicht vollständig, sondern bieten neue Optionen, die besser für neue Anforderungen sind. Ich erwarte, dass Serverless das vorherrschende Paradigma für neue Anwendungen wird (einschließlich Low- und No-Code-Anwendungen) und dass clevere Technologen Wege finden werden, Serverless in bestehende Technologie-Stacks zu integrieren. Die Mäuse und die Elefanten werden sozusagen zusammenleben(Abbildung 4-1).

Abbildung 4-1. Serverless und der Monolith

Die beiden Hauptgründe für die Einführung von Serverless sind folgende:

Geringerer Widerstand gegen Innovation

Jede Infrastruktur ist mit gewissen Reibungsverlusten verbunden, aber Serverless reduziert die Energieverschwendung beim Betrieb von Software.

Microbilling

Die Konzentration auf Arbeitseinheiten ermöglicht ein klareres Verhältnis zwischen den Kosten der Dienstleistung und dem erbrachten Wert.

Bei der ersten Einführung von Serverless mögen diese Vorteile gering sein, aber jede neue Serverless-Komponente erhöht den Nutzen für die Anwendung als Ganzes. Sobald die Vorteile einen Wendepunkt erreichen, wird Serverless zum Standard für ein Unternehmen, und die Tools und die Infrastruktur beginnen, diese Fähigkeiten auf eine eingebaute Weise zu nutzen. Schauen wir uns an, wie jeder dieser Treiber funktioniert und warum sich der Wert summiert.

Höchstgeschwindigkeit: Den Luftwiderstand reduzieren

Die meisten Service-Projekte beginnen mit einem oder einer kleinen Anzahl von Hauptserver-Prozessen - dies wird als Monolith-Modell der Entwicklung bezeichnet. Im Laufe der Zeit wird der Monolith mit immer mehr Funktionen ausgestattet, bis er das Ergebnis der Arbeit von zwanzig, fünfzig oder sogar hunderten von Entwicklern ist - eine Gesamtinvestition von hunderten oder tausenden von Entwicklungsjahren (ganz zu schweigen von den Jahren des Produktmanagers, den Jahren des Testens usw.). Schließlich erreichen Monolithen den Punkt, an dem sie so groß und anspruchsvoll sind, dass keine einzige Person die gesamte Anwendung versteht und Änderungen im großen Stil sehr schwierig werden. Selbst kleine Änderungen erfordern eine sorgfältige Planung und Überlegung, und die Arbeit an einem Monolithen gleicht dann eher einem großen Bauprojekt als einem Spaziergang im Park.

Als Reaktion auf diese Tendenz zur Verlangsamung der Geschwindigkeit in großen Projekten wurde dasMicroservice-Modell geboren. Bei diesem Modell ( ) wird jeder Teil der Funktionalität in einen separaten Dienst aufgeteilt und mit einer Mischung aus expliziten Remote-Aufrufen oder asynchronen Nachrichten zusammengefügt. Durch den Aufbau kleinerer Dienste wird es für einen Dienst schwieriger, einen anderen in seinen Implementierungsdetails zu verwickeln, und es wird einfacher, das Verhalten eines bestimmten Dienstes zu ändern, während die anderen Dienste konstant bleiben. Die genaue Größe der einzelnen Microservices ist Geschmackssache. Entscheidend ist, dass die Verträge zwischen den Microservices durch klare APIs ausgedrückt werden, die sich langsam und sorgfältig ändern.1

Zusätzlich zu den Antientropie-Eigenschaften, die sich aus der Trennung der Implementierungen unzusammenhängender Dienste ergeben, ermöglichen Microservices den Anwendungsteams die Auswahl der besten Implementierungssprachen und -werkzeuge für jede Aufgabe. Eine Bestelldatenbank kann zum Beispiel durch ein Java-Frontend und eine Postgres-Datenbank repräsentiert werden, während ein Produktkatalog in TypeScript mit einer Speicherung in MongoDB implementiert werden kann. Indem jeder Microservice in einen separaten Prozess aufgeteilt wird, können die Teams besser die Technologien auswählen, die zum Problemfeld passen - Python für KI-Probleme, Java für komplexe Domänenlogik, JavaScript oder TypeScript für Präsentation und Benutzeroberfläche und Erlang für paralleles, hochverfügbares Messaging.

Das FaaS-Modell setzt diesen Trend fort und zerlegt jeden Microservice in eine Reihe noch kleinerer Einheiten: Jeder einzelne Aufruf-Endpunkt oder Event-Handler wird als eigene Recheneinheit erstellt und bereitgestellt. Bei diesem Modell teilen sich sogar zwei verschiedene Methoden derselben API nicht denselben Rechenprozess und sind möglicherweise nicht einmal in derselben Sprache implementiert. Diese Trennung hat einige Vorteile:

Komponentenänderungen können unabhängig voneinander ausgeliefert werden

Da jede Funktion ein separater Dienst und eine Reihe von Serverprozessen ist, ist es möglich, eine Funktion zu aktualisieren, ohne den Rest des Systems zu beeinträchtigen (vorausgesetzt, das "Upgrade" funktioniert tatsächlich noch). Das bedeutet, dass Rollouts (und Rollbacks) den kleinstmöglichen Radius haben, wenn etwas schief läuft - schau dir an, was du zuletzt geändert hast, und mach diese Änderung rückgängig, um wieder zum Laufen zu kommen. Es ist erstaunlich, wie oft ein einfaches "Undo" ein System wieder zum Laufen bringt. Die Funktionen machen das Rückgängigmachen so einfach wie möglich.

Ressourcenzuweisungen können pro Methode bemessen werden

Wenn du einen Haufen zusammenhängender, aber unterschiedlicher Operationen in denselben Serverprozess packst, musst du die Worst-Case-Kombination dieser Operationen einplanen. Vielleicht muss die List-Operation 50 MB Arbeitsspeicher zuweisen, um eine Antwort zu deserialisieren, zu formatieren und zusammenzustellen, benötigt aber nur 0,1 Sekunden der CPU für die Berechnung. Die Operation Vorhersage hingegen benötigt 20 Sekunden CPU-Zeit für die Berechnung einer Antwort und speichert ein gemeinsames 200 MB großes Modell im Cache. Wenn du willst, dass jeder Server 10 Anfragen bearbeiten kann, musst du 200 + 10 × 50 = 700 MB RAM einplanen, um 10 Listen bearbeiten zu können, und 10 CPUs zuweisen, um 10 Vorhersagen zu bearbeiten. Du wirst nie beides auf einmal haben, aber du musst für den schlimmsten Fall planen.

Wenn du getrennte Funktionen für List und Predict zuweist, kann die List-Methode 500 MB RAM für 10 Anfragen benötigen (sie müssen das Vorhersagemodell gar nicht laden), aber nur 1 CPU. Die Predict-Methode hingegen benötigt 200 MB RAM und 10 CPUs für jede Instanz. Da du die beiden Arten von Anfragen trennst, kannst du die Größe der Predict-Instanzen verringern, indem du die Anzahl der Anfragen pro Instanz reduzierst. Angenommen, du verwendest ein serverloses Modell und skalierst diese beiden Methoden automatisch, dann würde ein Mix aus 34 Listen und 23 Predicts im klassischen Modell 6 Server und im FaaS-Modell 4 Listen- und 5 halb so große Predict-Server erfordern. Obwohl bei FaaS eine zusätzliche Instanz läuft, sind die benötigten Gesamtressourcen beim traditionellen Microservice-Modell um 60 bis 70 % höher. Monolithen leiden sogar noch mehr darunter; die Kapazitätsplanung für Monolithen kann je nach dem Grad der Interaktion zwischen den Komponenten ein erhebliches Hindernis darstellen.Tabelle 4-1 kann helfen, diese beiden Szenarien zu veranschaulichen.

Tabelle 4-1. Instanzanpassung für 34 List- und 23 Predict-Anfragen
Komponente Methoden Worst-Case-CPU Worst-Case-Speicher Instanzen Ressourcen

Gemeinsame Instanz

Auflisten und Vorhersagen, 10 gleichzeitige Anfragen

10 × 1,0 (Vorhersage)

200 MB (Modell) + 10 × 50 MB (Liste)

6

10 CPU, 700 MB RAM pro Instanz

Gesamt

6

100 CPUs, 7 GB RAM

Instanzen auflisten

Liste, 10 gleichzeitige Anfragen

10 × 0.1

10 × 50 MB

4

1 CPU, 500 MB RAM pro Instanz

Instanzen vorhersagen

Vorhersage, 5 gleichzeitige Anfragen

5 × 1.0

200 MB

5

5 CPUs, 200 MB RAM pro Instanz

Gesamt

9

29 CPUs, 3000 MB RAM

Angesichts dieser offensichtlichen Vorteile stellt sich die Frage, warum Microservices und FaaS nicht noch beliebter sind, als sie es heute sind? Wie du anhand des Titels dieses Abschnitts vielleicht schon vermutet hast, gibt es eine entgegengesetzte Kraft, die Teams zu Monolithen treibt:Reibung. Bei allen Vorteilen, die der Einsatz von Microservices anstelle von Monolithen mit sich bringt, besteht ein großer Nachteil von Microservices in der Vermehrung von kleinen Services, wie in Abbildung 4-2 dargestellt. Jeder Dienst muss gepflegt und gefüttert werden - wäre es nicht einfacher, nur ein großes Nilpferd zu füttern und zu pflegen, als hunderte von kleinen Hamstern, die alle einen eigenen Tierarzttermin brauchen?

Abbildung 4-2. Codegröße und Wartungsaufwand

Diese Reibung hat viele Ursachen: Einige sind in den Live-Diensten selbst begründet, andere werden durch verschiedene organisatorische Prozesse verursacht. Intrinsische Kosten entstehen zum Beispiel durch die Erstellung von Anwendungskonfigurationen, die Überwachung der Betriebszeit, die Aufrechterhaltung der API-Kompatibilität und die Erstellung von Artefakten. Externe Kosten, die durch organisatorische Prozesse verursacht werden, sind z. B. Launch-Reviews,Application Acceptance Testing oder Compliance-Audits. Externe Kosten sind nicht zwangsläufig schlecht - siesind Werkzeuge zum Erreichen von Geschäftszielen, die nicht von der zugrundeliegenden Technologie benötigt werden. Serverless kann dazu beitragen, die intrinsischen Kosten für den Betrieb einer Anwendung zu senken, indem die Konfiguration vereinfacht und die Überwachung automatisiert wird. Tools wie Continuous Delivery können dazu beitragen, sowohl die intrinsischen als auch die externen Kosten zu senken, indem sie den Build-, Test- und sogar den Audit-Prozess vereinfachen.

Jedes Team muss diese Kompromisse jedes Mal eingehen, wenn es eine neue Funktion oder Fähigkeit hinzufügen möchte - ob diese in einer bestehenden Delivery Unit wie einem Microservice oder in einer eigenen Unit untergebracht werden soll, was die Kosten für den "Betrieb eines Dienstes" noch weiter in die Höhe treibt, die das Team zu tragen hat. (Erinnere dich daran, dass das Team eine Reihe von laufenden Aufgaben hat, wie z. B. "die Unit-Tests im grünen Bereich halten" und "mit den Stakeholdern kommunizieren". Die zusätzliche Belastung durch die "Wartung von 273 Microservices" trägt zu Ermüdung und Burnout bei. Durch die Verringerung der Kosten für die "Wartung eines Dienstes" wird es für ein Team einfacher, sich entlang des Spektrums vonAbbildung 4-2 in kleinere Einheiten zu bewegen.

Kontinuierlich Wert schaffen

Microservices können also einfacher zu betreiben und zu warten sein und machen es einfacher, eine Komponente zu ändern, ohne dass dies kaskadenartige Auswirkungen hat. Im Gegenzug erfordern sie mehr Disziplin, wenn Änderungen vorgenommen werden, die Microservices betreffen. Aber warum reden wir hier über Microservices? Muss ich Serverless einführen, um Microservices zu betreiben?

Du brauchst Serverless nicht, um Microservices zu betreiben, und du brauchst Microservices nicht, um Serverless zu betreiben. Aber die beiden passen zusammen wie Erdnussbutter und Marmelade (oder was auch immer deine beiden Lieblings-Sandwich-Beläge sind). Im Folgenden gehen wir generell davon aus, dass du dich entschieden hast, deine Microservices auf Serverless laufen zu lassen, um von den inKapitel 1 beschriebenen betrieblichen Vorteilen und den Vorteilen, die ich im Folgenden beschreiben werde, zu profitieren.

Im Allgemeinen erleichtern Microservices die Umsetzung einer Reihe von modernen Bereitstellungspraktiken, darunter Datentrennung, progressive Bereitstellung und kontinuierliche Bereitstellung. Microservices machen es einfacher, die Bereitstellungspraktiken für jedes kleine Teil des Bereitstellungspuzzles zu ändern, ohne dass mehrere Handvoll Teams und Dutzende von Personen koordiniert werden müssen. Diese Verbesserungen bauen aufeinander auf, wobei die Datentrennung und die progressive Bereitstellung jeweils Fähigkeiten für das Endziel der kontinuierlichen Bereitstellung bieten:

Trennung der Daten

Gut strukturierte Microservices interagieren über explizite APIs miteinander, entweder direkt über RPC oder über asynchrones Messaging. So kann jeder Microservice seinen eigenen Datenspeicher über die vom Team gewählten Abstraktionen verwalten. Ein Team, das für die Verwaltung der Warenkörbe in einem Online-Shop zuständig ist, könnte zum Beispiel eine API für Bestellungen und Einzelposten bereitstellen. Das Kassensystem könnte eine separate API bereitstellen, die Bestellungen und Zahlungsmittel zur Durchführung einer Transaktion verbraucht.

Wenn die Teams die Abstraktionen wählen können, die sie anderen Teams zur Verfügung stellen, können sie die Schnittstellen in Form von Konzepten der Geschäftsdomäne und nicht in Form von Tabellen und Beziehungen definieren. Indem die Implementierung dieser Abstraktionen hinter einer API versteckt wird, kann das Microservice-Team die Speicherung und die Implementierungsentscheidungen hinter dem Microservice ändern, ohne dass andere Teams davon betroffen sind. Das kann bedeuten, dass eine bestehende Abfrage-API um einen Cache erweitert wird oder dass von einer relationalen Single-Instance-Datenbank auf eine skalierbare NoSQL-Datenbank migriert wird, um den erhöhten Speicher- und E/A-Bedarf zu bewältigen.

Die Datentrennung ermöglicht die folgenden Praktiken; ohne Datentrennung werden Anwendungsänderungen über Microservices hinweg gekoppelt, was die Umsetzung von Progressive oder Continuous Delivery erschwert.

Progressive Lieferung

Sobald Teams in der Lage sind, Änderungen an ihrer Microservice-Implementierung vorzunehmen, ohne die APIs zu beeinträchtigen, die sie für die Koordination mit anderen Diensten verwenden, besteht die nächste Herausforderung darin, diese Anwendungsbereitstellung sicher und wiederholbar zu machen. Progressive Bereitstellung ist eine Technik, mit der Änderungen in kleineren, sichereren Schritten vorgenommen werden. Anstatt den gesamten Microservice auf einmal auszurollen, wird eine Teilmenge der Anfragen an die neue Version weitergeleitet, wobei die Möglichkeit besteht, die Leistung und Stabilität der neuen Version zu bewerten, bevor der Großteil des Anwendungsverkehrs an die neue Version weitergeleitet wird. Blue-Green- und Canary-Deployments sind beliebte Beispiele für die schrittweise Bereitstellung, aber dies kann sich auch als Traffic Mirroring oder "Dark Launch" neuer Codepfade manifestieren, bei denen sowohl neue als auch alte Dienste aufgerufen werden.

Das Ziel der progressiven Auslieferung ist es, die Bereitstellung von Software sicherer zu machen, indem die Auswirkungen fehlerhafter Änderungen reduziert und die Zeit zur Wiederherstellung nach einer fehlerhaften Änderung verkürzt werden. Als grobe Faustregel gilt: Der Gesamtschaden eines Ausfalls ist das Produkt aus dem Radius (der Anzahl der betroffenen Nutzer) mal der Dauer des Ausfalls. Die schrittweise Bereitstellung zielt darauf ab, den Schaden einer fehlerhaften Einführung zu verringern und die Einführung von Software sicherer und schneller zu machen.

Kontinuierliche Lieferung

Wenn Teams in der Lage sind, Änderungen selbstständig auszurollen und die Auswirkungen fehlerhafter Konfigurationsänderungen zu reduzieren, können sie mit der Implementierung von Continuous Delivery beginnen. Zu diesem Thema wurden bereits ganze Bücher geschrieben, aber grob gesagt ist Continuous Delivery die Automatisierung der Softwarebereitstellung, so dass Software in regelmäßigen Abständen sicher ausgeliefert werden kann - täglich oder sogar bei jeder Codeänderung in einem Repository. Die Implementierung von Continuous Delivery bedeutet oft, dass alle Aspekte des Softwareerstellungs- und -freigabezyklus automatisiert werden und der automatisierte Freigabemechanismus mit der Anwendungsüberwachung verknüpft wird, sodass eine fehlerhafte Freigabe automatisch erkannt und zurückgenommen werden kann.

Wir haben bereits darüber gesprochen, wie Serverless das Anwendungsmanagement und den kontinuierlichen Betrieb vereinfachen kann, aber Serverless hat oft auch Vorteile, wenn es darum geht, das Nirwana der kontinuierlichen Bereitstellung zu erreichen.

Tipp

Bei Continuous Delivery geht es nicht darum, dass es nie zu einem Ausfall kommt oder der Rollout einer Software fehlschlägt. Das Ziel ist es, das Risiko der Softwareeinführung zu verringern, indem das Schadenspotenzial eines einzelnen Rollouts reduziert wird. Kleine, schnelle Rollouts verringern den Druck, der durch die Kombination von Must-Fix-Patches und großen neuen Funktionen entsteht. Die Aufteilung des Push-Umfangs verringert das Risiko, dass alles auf einmal scheitert. Die Automatisierung verringert das Risiko von Fehlern aufgrund von Prozessschwankungen.

Zwar erfordert Serverless keine Datentrennung (und ein Microservice kann tatsächlich als mehrere koordinierte Serverless-Prozesse implementiert werden, die sich eine gemeinsame Datenbank teilen), aber die API-Oberfläche, die über direkte RPC-Aufrufe oder asynchrones Messaging bereitgestellt wird, eignet sich gut für das Serverless-Unit-of-Work-Modell. Indem Teams motiviert werden, APIs zu definieren, die Serverless-Skalierungsmetriken vorantreiben können, implementieren sie auch skalierbare APIs vor ihren Anwendungsdatenquellen, und es wird einfacher, Teilbereiche der Anwendung zu definieren, die mit einer bestimmten Datenquelle interagieren und zusammengeschoben werden müssen.

Progressive Delivery wird oft direkt von der serverlosen Laufzeit unterstützt. Da die serverlose Laufzeit die Arbeitseinheiten bereits kennt, sind oft Mechanismen in das Framework eingebaut, die eine Aufteilung oder Weiterleitung dieser Einheiten an bestimmte Anwendungsversionen ermöglichen. Knative und viele FaaS-Angebote bieten zum Beispiel die Möglichkeit, den Datenverkehr zwischen Anwendungsversionen aufzuteilen, die von der Runtime bei der Bereitstellung automatisch verfolgt werden.

Abgerundet wird die Beschleunigung der Anwendungsbereitstellung durch serverlose Plattformen, die eine kontinuierliche Bereitstellung unterstützen können, da sie in der Lage sind, wichtige Anwendungsmetriken auf der Ebene der einzelnen Arbeitseinheiten zu verfolgen. Latenz, Durchsatz und Fehlerrate sollten durch die Integration mit dem Monitoring-Stack der Plattform für die Automatisierung der Bereitstellung zugänglich sein. Natürlich sind einige Verteilungskennzahlen (wie z. B. die Anzahl der erfolgreichen Warenkorb-Bestellungen) ohne Metriken auf Anwendungsebene für die Verteilungsmaschinerie nicht verfügbar, aber eine allgemeine Überwachung der Arbeitseinheiten kann einen grundlegenden Leistungsumfang liefern, der für viele Teams geeignet ist. In Kapitel 10 werde ich mehr über die Überwachungsfunktionen von serverlosen Plattformen erzählen.

Das (Geschäfts-)Rennen gewinnen

Es macht Spaß Code zu pushen und ihn innerhalb von 30 oder 60 Minuten live auf der Produktionsseite erscheinen zu lassen, aber der wirkliche Vorteil von Continuous Delivery liegt darin, dass die technologischen Grenzen der Reaktionszeit von Unternehmen aufgehoben werden. Durch die Bereitstellung eines unterstützenden Gerüsts für die Implementierung von Continuous Delivery können Unternehmen, die ein Serverless-First-Entwicklungsmodell implementieren, schneller auf veränderte Kundenbedürfnisse reagieren und agiler experimentieren als Unternehmen, die sich um einen Monolithen kümmern müssen.

Zusammenfassend lässt sich sagen, dass Unternehmen in zweierlei Hinsicht von der Einführung einer serverlosen Microservices-Architektur profitieren:

Geringere Arbeitsbelastung

In der Vergangenheit bestand der Hauptvorteil von Monolithen darin, dass sich ein einziges Betriebsteam spezialisieren und auf den Aufbau einer Ausführungsplattform konzentrieren konnte, die alle Anwendungen auf einem oder einer festen Anzahl von Servern verwaltete (man denke an cgi-bin oder J2EE-Anwendungsserver, die Dutzende von Mikroanwendungen auf einen einzigen Server laden). Microservices bedeuten, dass Dutzende von Servern mit jeweils nur einer einzigen Anwendung unterhalten werden müssen, was zu einem erhöhten Betriebsaufwand führt, da jeder Server für die installierte Anwendung einzigartig ist. Durch die Vereinfachung des Anwendungsbetriebs und die Automatisierung einiger gängiger täglicher Überwachungsaufgaben kann ein Großteil der Mühen einer Microservices-Architektur vermieden werden.

Gerüst für kontinuierliche Bereitstellung

Wenn reduzierter Aufwand die aerodynamische Hülle für Anwendungen ist, ist Continuous Delivery der Turbolader. Die Verkürzung der Vorlaufzeit für Änderungen ist eine der wichtigsten Kennzahlen, die vonDevOps Research and Assessment verwendet werden, um Unternehmen zu identifizieren, die bei der Ausführung von Software eine Spitzenposition einnehmen. Da Software in immer mehr Bereiche des Geschäftslebens Einzug hält, ermöglicht die kontinuierliche Bereitstellung eine schnellere Reaktion auf ungewisse Ereignisse in der Welt. Die Straffung der Beobachtungs-, Entscheidungs- und Handlungsschleife hilft Unternehmen, mit allem Schritt zu halten, was die Welt ihnen vorsetzt.

Wir hoffen, dass diese Argumente erklären, wie Serverless Organisationen helfen kann, bessere und schnellere Entscheidungen zu treffen. Im nächsten Abschnitt wird erklärt, wie Serverless Unternehmen helfen kann, intelligentere Entscheidungen zu treffen.

Microbilling

Im vorigen Abschnitt ging es um die Aufteilung monolithischer Anwendungen in Microservices unter dem Gesichtspunkt der Anwendungsbereitstellung und der Bequemlichkeit der Entwicklungsteams. Wir werden jetzt über etwas sprechen, das für die Entwicklungsteams sehr unangenehm seinkann, das aber ein faszinierendes Licht auf den wirtschaftlichen Status eines Unternehmens werfen kann: die Kosten für die Bereitstellung von Waren und Dienstleistungen (auch bekannt als Umsatzkosten oder COGS für alle BWL-Studenten da draußen).

Es mag einige von euch überraschen zu erfahren, dass viele Unternehmen ihre EDV-Kosten nicht verstehen. Die anderen nicken zustimmend und sagen: "Evan, komm endlich zur Sache." Durch die Aufteilung von Monolithen in Microservices und die Verfolgung von Arbeitseinheiten ist es möglich, Rechenkosten für einzelne Geschäftsbereiche zuzuordnen, manchmal sogar bis auf Transaktionsebene!

Auch wenn die Kosten auf einer feinkörnigen Ebene gemessen werden können, ist die Kapitalrendite (ROI) unter Umständen viel schwieriger zu berechnen. Kundenbindungsprogramme haben zum Beispiel leicht messbare Kosten, aber einen schwer messbaren Beitrag zur Kundentreue und zu Folgeverkäufen.

Durch die Aufteilung der Kosten auf einer feingranularen Ebene wird es einfacher zu verstehen, welche Dienste sowohl den Gewinn als auch den Umsatz steigern. Wenn es z. B. 0,50 USD kostet, einen Nutzer über eine Text-Chat-Anwendung anzusprechen, kannst du diese Kosten mit den Kosten vergleichen, die entstehen, wenn du einen menschlichen Mitarbeiter für 15 USD pro Stunde anstellst, um Textfragen zu beantworten; wenn der Mensch mehr als 30 Kunden pro Stunde beantworten kann, ist er tatsächlich billiger als die Anwendung, wenn man die Schulungs- und App-Entwicklungskosten außer Acht lässt. Außerdem kannst du vielleicht eine bestimmte KI-Komponente ausfindig machen, die 0,30 USD des Interaktionspreises ausmacht, und sie optimieren - entweder indem du sie von der CPU auf die GPU verlagerst oder umgekehrt, oder indem du das Modell selbst veränderst, um die Kosten zu optimieren.

Ein Deal mit der Cloud

Die Abrechnung von bis zur einzelnen Arbeitseinheit ist am einfachsten bei Cloud-Providern, die serverlose Plattformen anbieten und oft direkt die geleistete Arbeit abrechnen, manchmal sogar bis auf die Millisekunde genau. Bei serverlosen Angeboten von Cloud-Providern ist der Cloud-Provider für die Bereitstellung ausreichender Kapazitäten und die Verwaltung der zusätzlichen ungenutzten Kapazitäten verantwortlich. Der Cloud-Provider wiederum kassiert einen Teil des Mehrwerts, der sich aus der Illusion unendlicher Kapazität ergibt. Einigen Studien zufolge sind serverlose Berechnungen etwa viermal so teuer wie Standard-IaaS-Instanzen wie Amazon Elastic Compute Cloud (EC2) (die wiederum einen Aufpreis gegenüber Installationen vor Ort verlangen). Auch wenn Cloud-Provider ihre Preisgestaltung ändern können und dies auch tun, werden serverlose Angebote aufgrund ihres Nutzens wahrscheinlich weiterhin pro Kapazität teurer sein als weniger flexible Infrastrukturen.

Da Cloud-Provider in der Regel entweder auf der Grundlage von Arbeitseinheiten (d. h. Funktionsausführungen) oder der CPU- oder Speicherbelegungszeit bei der Bearbeitung von Anfragen abrechnen, ist es einfach, die Kosten für einen bestimmten Microservice auf die Aufrufer dieses Dienstes und die zugehörigen Anwendungsstacks umzulegen. Es ist möglich, die Vorteile der Skalierung auf Null zu nutzen, indem man mehrere Kopien eines Microservices einsetzt, eine für jede Anwendung, aber das ist in der Regel nicht nötig, da sich die Kosten pro Anfrage leicht über die Preise des Cloud-Providers ermitteln lassen.

Während die Zuordnung von Gebühren pro Anfrage zur Anwendungsnutzung bei Single-Thread-Anwendungen mit einer Anfrage pro Instanz recht gut funktioniert, kann die Abrechnung bei Plattformen wie Googles Cloud Run (oder Knative), bei denen mehrere Anfragen gleichzeitig von einer Instanz bearbeitet werden können, etwas komplizierter werden. Der Hauptvorteil des komplexeren Ausführungsmodells von Cloud Run oder Knative ist, dass viele serverlose Anwendungen eine beträchtliche Zeit mit dem Warten auf API- oder Service-Antworten verbringen. Da die "Wall Time" häufig als Abrechnungsmaßstab für die Speicher- und CPU-Auslastung verwendet wird, kann dies das Multithreading und die Bearbeitung mehrerer Anfragen in einer einzigen Instanz zu einer attraktiven Möglichkeit machen, auch wenn die Abrechnung dadurch etwas schwieriger wird. Die Effizienzgewinne, die sich aus dem Multiplexen von Anfragen ergeben, sind in Abbildung 4-3 zu sehen, wo eine doppelt so große Instanz viermal so viele Arbeitseinheiten bearbeiten kann - das wäre eine Kostenersparnis von 50 %!

Abbildung 4-3. Bearbeitung mehrerer Anfragen pro Instanz

Selbst wenn du ein komplexeres Multithreading-Modell wie Knative verwendest, funktioniert die Durchschnittsbildung der Kosten über alle Anfragen im Allgemeinen gut, es sei denn, du kombinierst Anfragen mit sehr unterschiedlichen Ausführungsprofilen in einem Microservice. Ein gängiges Beispiel sind die Anfragen Get und List - erstere lesen in der Regel eine einzige Datenbankzeile, während letztere möglicherweise Tausende von Datenbankzeilen lesen, die Ergebnisse herausfiltern oder große Datenmengen zusammenfassen. Die Aufteilung von Get und List in verschiedene Funktionen oder Microservices kann den Konflikt zwischen den beiden reduzieren, aber auch die betriebliche Komplexität für einen begrenzten Nutzen erhöhen, also prüfe, bevor du diesen Rat blindlings anwendest.

Eine letzte Warnung: Die Nutzung von serverlosen Diensten kann versteckte Kosten verursachen, die bei der Ermittlung der Anfragekosten schwieriger zu berücksichtigen sind. Hier sind ein paar Beispiele:

Netzwerk-Ausgang

Nahezu jeder Cloud-Provider berechnet die gesendeten Netzwerk-Bytes separat. Hoffentlich kann deine serverlose Plattform den Anteil der gesendeten Bytes melden, der auf deine serverlosen Anwendungen zurückzuführen ist, aber die Abrechnung des gesamten Datenverkehrs kann manchmal schwierig sein.

Datensysteme

Einige wenige Datenbanksysteme können sich wirklich "serverlos" nennen, aber die meisten sind immer noch an eine relativ feste Anzahl von Servern oder eine Primär-/Replikat-Topologie gebunden. Da serverlose Systeme ihre Speicherung in der Regel auslagern, sind Datendienste ein versteckter Kostenfaktor, der nur schwer in den Kosten für Waren und Dienstleistungen berücksichtigt werden kann.

Multitier-Dienste

Wenn eine Anwendung in mehrere Softwareschichten zerlegt wird, ist zusätzliche Arbeit erforderlich, um zu verstehen, wie die Backend-Kosten auf der Grundlage der Frontend-Vorgänge zugewiesen werden sollten. Wenn alle Systeme serverlos sind, kann das verteilte Tracing (siehe "Tracing") die Zuordnung von Frontend- zu Backend-Kosten liefern. Wenn die Backends nicht serverlos sind, können die Kosten auf die gleiche Weise undurchsichtig werden wie die Datendienste.

Trübungen auf eigene Faust

Es gibt viele gute Gründe, warum du dich dafür entscheiden könntest, eine serverlose Plattform selbst zu entwickeln, anstatt dich auf das Angebot eines Cloud-Providers zu verlassen - bestehende Investitionen oder Kostensensibilität, fehlende Cloud-Fähigkeiten (z. B. GPU-Unterstützung oder die Integration bestimmter Funktionen), Anforderungen an Kanten und physische oder behördliche Datenverarbeitung oder der Wunsch nach konsistenten Tools über verschiedene Clouds hinweg sind alles gute Gründe. Heißt das, dass du den Traum von serverlosen Kostenmodellen und dem Verständnis deiner Kosten für die Bereitstellung von Diensten aufgeben musst? Ganz sicher nicht!

Wenn die Cloud-Provider das können, ist das keine Zauberei. Es ist höchstens etwas kompliziert, aber es ist möglich, ein eigenes Kostenmodell für die Berechnung zu erstellen - mit Tools wie Kubecost können Kubernetes-Plattformen die Kosten auf der Grundlage von Metriken und Cloud-Ökonomie für VMs, Netzwerke und Speicherung berechnen. Mit diesen Plattformen kannst du anhand von Überwachungsdaten die von jedem Pod verbrauchten Ressourcen ermitteln, sie nach Komponenten zusammenrechnen (sowohl für serverlose als auch für serverlastige Dienste) und diese Kosten dann einzelnen Gruppen zuweisen.

Es ist auch möglich, dass diese Tools die Kosten der zugrundeliegenden Plattform amortisieren (teilen): Load Balancer, Node Agents, Überwachung, Logsammlung usw. haben alle Kosten, die typischerweise in einer mandantenfähigen Form zum Nutzen aller Nutzer betrieben werden. Diese Kosten können durch viele Richtlinien aufgeteilt werden - gleiche Kosten pro Anwendung, gleiche Kosten pro genutzter Rechenminute oder Kosten pro reservierter/bereitgestellter Rechensekunde sind alles vernünftige Ansätze, die in der Praxis verwendet werden.

Die Bilanzierung von bereitgestellter, aber ungenutzter Kapazität kann in dieser Welt knifflig sein; physische oder virtuelle Maschinen, die eingeschaltet sind, aber keinen Anwendungscode ausführen, können entweder als unterstützende Plattformkosten umgelegt oder von der Organisation als "Verlustbringer" akzeptiert werden, um interne Kunden auf die Plattform zu locken. In einigen Fällen können Organisationen einen Teil oder einen großen Teil dieser Kosten durch Overprovisioning (den doppelten Verkauf derselben Kerne oder desselben Speichers, wobei einige bekannte Ineffizienzen vorausgesetzt werden) oder durch die im nächsten Abschnitt beschriebene opportunistische Arbeit wieder hereinholen.

Was passiert, wenn du nicht läufst

Bisher haben wir darüber gesprochen, wie Serverless funktioniert, um deine Anwendung auszuführen, aber wir haben nicht viel darüber gesprochen, was mit den Servern passiert, wenn keine Anwendungsarbeit zu erledigen ist. Eine Möglichkeit ist es, die Prozessoren einfach in einen stromsparenden Zustand zu versetzen; das kann bei neueren x86-Prozessoren Hunderte von Watt Strom sparen. Die Hardware ist immer noch da, und andere Komponenten wie RAM, Festplatten und Add-in-Karten verbrauchen ebenfalls nicht unerhebliche Mengen an Strom, erzeugen Wärme und belasten die Systeme des Rechenzentrums wie Kühlung, Netzwerk und Stromverteilung. Ich habe wirklich das Gefühl, dass wir mit dieser Kapazität etwas Besseres anfangen können sollten. (Und nein, ich rede nicht vom Mining von Bitcoin!)

Wie ich im vorigen Abschnitt angedeutet habe, kann diese Basiskapazität unter anderem für opportunistisches Computing genutzt werden. Systeme wie Kubernetes ermöglichen es, Arbeit auf verschiedenen Prioritätsstufen zu planen. CPUs, die mit Aufgaben hoher Priorität ausgelastet sind, können Zeitscheiben für Arbeit mit niedriger Priorität zuweisen und gleichzeitig bereit sein, diese Arbeit zu pausieren, wenn eine neue Aufgabe hoher Priorität eintrifft.

Abhängig von deinem Betriebskomfort kannst du diese ungenutzte Kapazität auf verschiedene Weise nutzen:

Stapelberechnung

Viele Unternehmen sammeln große Datenmengen für spätere Analysen; diese Analysen werden oft am nächsten Arbeitstag oder unter ähnlich engen Zeitvorgaben benötigt. Indem diese Arbeit mit geringerer Priorität auf denselben Ressourcen ausgeführt wird, die von Serverless verbraucht werden, kann die Batch-Arbeit zu Zeiten abgeschlossen werden, in denen die interaktive Echtzeit-Nachfrage nach Arbeit geringer ist. Batch-Workloads sind oft tatsächlich serverlos - "alle diese Datensätze abbilden" oder "alle diese Kombinationen reduzieren" werden beide nach Arbeitseinheiten skaliert. Dieses Muster funktioniert gut bei peinlich parallelen Problemen, kann aber bei Batch-Workloads, bei denen jeder Worker eine direkte Verbindung zu anderen Workern herstellen muss, sehr ineffizient sein. Wenn diese direkten Verbindungen ins Stocken geraten, weil der Absender oder das Ziel Ressourcen an einen serverlosen Prozess verliert, kann dies zu kaskadenartigen Verzögerungen bei Hunderten von Aufgaben führen.

Dienstleistungen aufbauen

Software-Builds sind eine weitere Möglichkeit, die Arbeit zu parallelisieren und die Entwicklungsgeschwindigkeit zu erhöhen. Dies gilt auch für andere rechenintensive Prozesse wie 3D-Rendering oder das Training von KI-Modellen. Anstatt teure Laptops bereitzustellen, bei denen die Lüfter anspringen und die Videokonferenzen stottern, können die Nutzer/innen diese Aufgaben von ihrem lokalen Rechner auf freie Kapazitäten auslagern, die zwischen den Nutzungsspitzen vorübergehend verfügbar sind. Dieses Modell eignet sich besser für große Builds oder Renderings, die einige Minuten bis Stunden dauern können; es lohnt sich selten, den gesamten Status eines einminütigen Builds in die Cloud zu verlagern.

Entwicklung und Forschung

Wenn genügend freie Kapazitäten zur Verfügung stehen und die serverlosen Aufgaben stark isoliert sind, kann eine Organisation beschließen, den Entwicklungsteams zu erlauben, die ungenutzten Kapazitäten mit niedriger Priorität für Entwicklungsumgebungen oder kleine Forschungsprojekte zu nutzen. Dies kann sowohl ein Vorteil für die Entwicklungsteams als auch eine Chance für Innovationen innerhalb der Organisation sein.

Die Gravitationskraft von Serverless

Ich hoffe, ich habe dich davon überzeugt, dass Serverless keine Eintagsfliege ist, sondern sich durchsetzen wird. Außerdem werden die überzeugenden Vorteile der serverlosen Entwicklung dazu führen, dass Serverless einen immer größeren Marktanteil gewinnt, so wie Minicomputer, Desktop-Anwendungen, Webservices, APIs und Mobiltelefone neben den bereits bestehenden Modellen der Anwendungsentwicklung Marktanteile gewonnen haben.

Wenn du davon ausgehst, dass Serverless einen immer größeren Einfluss auf das tägliche Computing und die Anwendungsentwicklung haben wird, dann ist es nur logisch, dass auch andere Technologien wachsen und sich weiterentwickeln werden, um Serverless besser zu unterstützen. So wie JavaScript mit dem Aufkommen von web- und browserbasierten Anwendungen allgegenwärtig wurde, werden Sprachen, Tools und die Computing-Infrastruktur neuen Druck auf das Computing ausüben. Tools, die diese Herausforderungen meistern, werden wachsen und gedeihen (Ruby on Rails und PHP wurden beispielsweise für das Web entwickelt), während Anwendungen, die dafür nicht geeignet sind, ihre Nischen behalten werden (in 40 Jahren werden wir immer noch COBOL-Programmierer/innen brauchen, um Banken bei der Verwaltung ihrer Mainframe-Anwendungen zu helfen).

Auswirkungen auf die Sprachen

Der Schwerpunkt von Serverless auf der Verwaltung von Arbeitseinheiten stellt eine Verbindung zu zwei bestehenden Sprachmustern her: Inversion der Kontrolle und reaktive Designprinzipien. Inversion der Kontrolle,2 ist ein Modell, bei dem das Framework den Programmfluss kontrolliert und anwendungsspezifischen Code zu bestimmten Zeiten aufruft. Beim reaktiven Programmiermodell drücken sich die Anwendungen als eine Reihe von Reaktionen auf Änderungen an vorgelagerten Datenquellen aus.3 Durch die Auslagerung dieser Muster aus bestimmten Sprachen wird der Zugang zu diesen Fähigkeiten demokratisiert, ohne dass spezielle Sprachframeworks oder Tools verwendet werden müssen. Serverlose Systeme sind zum Beispiel von Natur aus elastisch bei unterschiedlichem Arbeitsaufkommen, und das Paradigma der Arbeitseinheiten lässt sich sowohl mit Kontrollflüssen nach dem Motto "Ruf mich nicht an, ich rufe dich an" als auch mit einem nachrichtengesteuerten Kommunikationsmodell gut umsetzen.

Serverless bietet zwar ein Gerüst zur Unterstützung bestehender Sprach- und Systementwurfsmuster, bringt aber auch neue Anforderungen mit sich:

Schnelles Starten

Die Ausführung der Anwendung an die verfügbare Arbeit zu koppeln, bedeutet, dass serverlose Systeme tendenziell häufiger Skalierungsvorgänge durchführen als traditionelle Systeme. Das bedeutet wiederum, dass der Start (und das Herunterfahren) der Anwendung schnell sein und eine geringe Last erzeugen sollte. Kompilierte Sprachen und Sprachen mit leichtgewichtigen JIT-Prozessen haben einen Vorteil gegenüber Sprachen mit schwergewichtigen JIT- oder Modulimportprozessen, die bei jedem Anwendungsstart ausgeführt werden müssen.

Umgang mit Misserfolgen

Da serverlose Systeme in hohem Maße auf der Skalierung nach Arbeitseinheiten beruhen, verwenden sie oft externe Dienste, um den Status zu speichern oder als Microservice-Grenzen. Das bedeutet, dass Anwendungen, die im serverlosen Stil erstellt wurden, vielen Aufrufen von Remote-Diensten ausgesetzt sind, von denen jeder einzelne aufgrund von Netzwerkproblemen fehlschlagen oder eine Zeitüberschreitung verursachen kann.

Netzwerkspeicherung vor Festplattenspeicherung

Die Speicherung auf der lokalen Festplatte in serverlosen Umgebungen ist in der Regel sehr kurzlebig. Daher ist die Fähigkeit, schnell auf Dateien auf der lokalen Festplatte zuzugreifen und diese zu verwalten, möglicherweise weniger wichtig als bei traditionellen Anwendungen, bei denen Caches oder vorberechnete Ergebnisse auf der Festplatte gespeichert werden, um spätere Arbeiten zu vermeiden. Gleichzeitig kann die Fähigkeit, Netzwerkspeicherdienste aufzurufen und den Zustand außerhalb der serverlosen Instanz zu externalisieren, wichtiger sein als in traditionellen Systemen. So ist die Fähigkeit, einfach auf Systeme wie Redis oder Objektspeicher wie S3 zuzugreifen, wichtiger, wenn die lokale Speicherung wirklich flüchtig ist.

Serialisierung

Zwar müssen alle Anwendungen Daten serialisieren und deserialisieren, aber bei serverlosen Anwendungen kann sowohl die Einfachheit (für die Entwickler) als auch die Geschwindigkeit und Effizienz (für die Computer) der Serialisierung und Deserialisierung von Daten eine zusätzliche Rolle spielen. Da serverlose Architekturen in der Regel aus Microservices und unterstützenden Datendiensten bestehen, die jeweils ihre eigene Speicherung oder ihre eigenen Netzwerkformate haben, ist die Fähigkeit, Daten effizient und einfach über verschiedene Endpunkte hinweg zu serialisieren und zu deserialisieren, zunehmend wichtig.

Auswirkungen auf Sandboxing

Traditionelle Anwendungen haben VMs und Linux-Container verwendet, um Anwendungen in eine Sandbox zu stellen. Diese Tools sind gut erprobt und werden gut verstanden, aber sie führen zu erheblichen Leistungsproblemen beim Start sowie zu Overhead für Kernel, Shared Libraries und Netzwerkschnittstellen. Die Startzeiten für VMs mit einem Allzweck-Betriebssystem können Dutzende von Sekunden betragen, während Linux-Container Hunderte von Millisekunden an Einrichtungszeit benötigen können.

Neuere Technologien wie Wasm und Service Worker in der JavaScript-Laufzeitumgebung ermöglichen die Definition viel restriktiverer Sandboxen (nur eine Handvoll benutzerdefinierter E/A-Methoden), die innerhalb von zehn Millisekunden hochgefahren werden können und pro Sandbox einen Overhead von einem Megabyte oder weniger haben. Plattformen wie Cloudflare Workers zeigen, wie vielversprechend dieser Ansatz ist. Allerdings gibt es auch erhebliche Einschränkungen, die wahrscheinlich bedeuten, dass alle Sandbox-Ebenen noch lange Zeit nebeneinander existieren werden.4

Auswirkungen auf den Werkzeugbau

Das serverlose Paradigma eignet sich hervorragend für Entwickler-Tools (und allgemeine Tools für Nicht-Entwickler). Tools und Automatisierung lassen sich in der Regel gut in Arbeitseinheiten unterteilen - das Erstellen einer Binärdatei, das Generieren einer API, das Bearbeiten eines Tickets oder das Beantworten einer Textnachricht. Angesichts des Umfangs einer typischen Funktion können Integrationstests für einen Großteil der Anwendungsabdeckung ein gangbarer Weg sein, anstatt sowohl Unit- als auch Integrationstests durchführen zu müssen.

Für Entwickler ist GitHub Actions ein gutes Beispiel für eine serverlose Tooling-Plattform. Entwickler können Aktionen schreiben, die sich auf einen einzelnen Commit, Pull Request oder Release beziehen und müssen sich keine Gedanken über lang laufende Server, Job Scheduling und Gleichzeitigkeit oder die Verbindung von Plattformkomponenten und Diensten machen. Für Nicht-Entwickler/innen bieten Dienste wie IFTTT (If This Then That), die einfache Automatisierungen zwischen paketierten Diensten ermöglichen, eine ähnliche serverlose Erfahrung, ohne dass sie Code oder Automatisierungsskripte schreiben müssen.

Mit einer einfach zu bedienenden Plattform für Anwendungen profitieren Tools wie Low- und No-Code Application Builder und Integrationsplattformen von Serverless als zugrunde liegendes Anwendungssubstrat. Da es bei Anwendungen immer weniger um große, kontinuierlich ablaufende Prozesse geht, sondern vielmehr um kleine Mengen an Glue zwischen bestehenden Diensten, ergänzen sich Low-Code- und Serverless-Ansätze, indem sie die Anforderungen an die Nutzer/innen beim Schreiben und Verwalten von Anwendungen reduzieren.

Auswirkungen auf die Sicherheit

Serverlose Prozesse neigen dazu, in einem Pool von Hosts häufig hoch- und heruntergefahren zu werden. Sicherheitstools auf Instanzebene können in einer dynamischen Umgebung wie dieser nur schwer eingesetzt werden, weshalb Tools auf Clusterebene wichtiger und relevanter sind. Gleichzeitig kann die flüchtige Natur von serverlosen Prozessen den Verteidigern einen Vorteil verschaffen, da die natürliche Fluktuation der Instanzen den Angreifern nach dem anfänglichen Erfolg des Angriffs den Boden unter den Füßen wegziehen kann.

Betrachtet man die historischen Trends, so scheint Serverless die Fähigkeit der Verteidiger zu verbessern, ein konsistentes Patching auf Betriebssystemebene zu gewährleisten. Konsistente Paketierungsformate wie OCI-Container können auch bei der Indizierung und Sichtbarkeit von Anwendungen helfen, die mit anfälligen Bibliotheken und Daten erstellt wurden. Leider manifestieren sich viele der schwerwiegenden Sicherheitslücken als Fehler auf Anwendungsebene, wie z. B. unzureichende Eingabevalidierung, Zugriffskontrollfehler und Designfehler. Serverlose Funktionen sind weitgehend unabhängig von diesen Fehlern; sie sind für ephemere und persistente Instanzen gleichermaßen gravierend und müssen an anderer Stelle im Softwareentwicklungsprozess behoben werden.

Auswirkungen auf die Infrastruktur

Die offensichtlichsten Herausforderungen für die Infrastruktur, die serverlose Anwendungen unterstützt, betreffen das Starten von Anwendungen (insbesondere Kaltstarts, wenn eine Anfrage im Gange ist) und die Schaffung der Illusion einer unendlichen Kapazität und Geschwindigkeit. Zusätzlich zu den erwähnten Kaltstartproblemen auf Sprachebene muss die Infrastruktur den Anwendungscode zur kaltstartenden Instanz bringen und dieses Problem für viele Instanzen gleichzeitig lösen. Abgesehen von den Startzeiten müssen serverlose Plattformen auch das Kostenmanagement, die effiziente Bereitstellung und das Deprovisionieren von Instanzen sowie die Konnektivität aller Instanzen zur und von der Plattform berücksichtigen.

Neben den bereits erwähnten alltäglichen Herausforderungen von serverlosen Plattformen gibt es einige größere Herausforderungen mit serverlosen Infrastrukturen, deren Lösungen nicht offensichtlich sind oder "mehr vom Gleichen, aber schneller".

Eine der Herausforderungen bei der Datenverarbeitung ist die Frage, ob man "Daten zu Code" oder "Code zu Daten" liefern soll. Bei den aktuellen serverlosen Architekturen werden hauptsächlich Daten an den Code geliefert, obwohl Verbesserungen beim Sandboxing mit Wasm dieses Gleichgewicht ändern könnten. Während viele Anwendungen so klein sind, dass die beiden Ansätze ähnliche Kosten verursachen, gibt es in den meisten Unternehmen zumindest einige datenintensive Anwendungen, bei denen der Aufwand für die Übertragung und Konvertierung von Daten zwischen verschiedenen Formaten die Gesamtkosten dominiert. Die Möglichkeit, diese Plattformen serverlos zu betreiben und die daraus resultierenden Geschwindigkeits-, Kosten- und Effizienzvorteile zu nutzen, ist ein offenes Problem.

Eine weitere Herausforderung im Zusammenhang mit Serverless ist der Umgang mit ineinandergreifenden Arbeitseinheiten. Solange jede Arbeitseinheit unabhängig ist, ist es einfach zu verstehen, wie man das Problem skalieren und unterteilen kann, damit verschiedene Computer an unterschiedlichen Aspekten arbeiten können. Leider bestehen manche Probleme aus einer Mischung aus leicht unterteilbarer Arbeit und Arbeit, die die leicht unterteilbaren Teile zu einem kohärenteren Ganzen zusammenfügt. Physikalische Simulationen, die Verarbeitung von Datenströmen und das Training neuronaler Netze sind alles Beispiele dafür, dass einige Aufgaben sehr unabhängig sind, während andere Aufgaben eine enge Koordination zwischen den einzelnen Computerkomponenten erfordern. Serverless kann zwar für die leicht zu trennenden Teile verwendet werden, aber es ist nicht sehr hilfreich, Plattformen und Paradigmen zu wechseln, um die Vorteile von Serverless nur für einen Teil der Lösung zu nutzen. Mechanismen, die eine einfache Brücke zwischen serverlosen und konventionellen Berechnungsmustern schlagen, werden dazu beitragen, die Bandbreite der Probleme zu erweitern, die serverlos gelöst werden können.

Zusammenfassung

Bei Serverless geht es nicht nur darum, den Betrieb von Softwarediensten zu vereinfachen. Einfachere Software-Dienste machen neue Architekturen möglich, was wiederum Teams und Organisationen erlaubt, ihr Modell der Anwendungsentwicklung zu ändern. Neue Wege der Anwendungsentwicklung (und neue Tools, die diese Muster unterstützen) verändern die Bedingungen für die Bereitstellung und das Testen von Software. Neue Wege, Anwendungen zu betreiben, ermöglichen neue Geschäftsprozesse wie die Bewertung der Betriebskosten und des ROI von Softwareinitiativen. Im nächsten Teil werden wir sehen, wie man Serverless auf die Systemarchitektur und das Softwaredesign anwendet, um diese Vorteile zu nutzen - aber die Softwarearchitektur dient den Bedürfnissen des Unternehmens, nicht umgekehrt!

1 Wenn sich die APIs zwischen diesen Komponenten schnell und nachlässig ändern, so dass Pushs zwischen den Komponenten koordiniert werden müssen, hast du möglicherweise einen verteilten Monolithen. Dies ist sowohl ein kulturelles als auch ein technisches Problem.

2 Manchmal wird es mit dem Hollywood-Prinzip beschrieben: "Ruft uns nicht an, wir rufen euch an."

3 Die reaktive Programmierung hat zwar keinen so klaren Slogan wie die Umkehrung der Kontrolle, aber sie hat beeindruckende Leistungsverbesserungen im Vergleich zu einem traditionellen Thread-per-Request-Modell gezeigt.

4 Weitere Details zu Cloudflare Workers findest du im Vortrag von Kenton Varda auf der QCon London 2022: "Fine-Grained Sandboxing with V8 Isolates".

Get Serverlose Anwendungen auf Knative aufbauen now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.