Microservices im Spätstadium

May 09 2023
Ich habe von den Bemühungen des Amazon Prime Video-Teams gelesen, die Kosten zu skalieren und um 90 % zu senken, indem es seine Microservices zu einem Monolithen kombiniert. Obwohl ich mir sicher bin, dass die Geschichte hier noch mehr beinhaltet, gibt es im Internet ähnliche Geschichten; eine Art Widerlegung des Microservices-Wahnsinns des letzten Jahrzehnts.

Ich habe von den Bemühungen des Amazon Prime Video-Teams gelesen, die Kosten zu skalieren und um 90 % zu senken , indem es seine Microservices zu einem Monolithen kombiniert. Obwohl ich mir sicher bin, dass die Geschichte hier noch mehr beinhaltet, gibt es im Internet ähnliche Geschichten ; eine Art Widerlegung des Microservices-Wahnsinns des letzten Jahrzehnts.

Es erinnerte mich an die letzten Jahre, die ich bei Twitter verbrachte, als die Zahl der Microservices (in Tausenden) ihren Höhepunkt erreichte und dann zu sinken begann, obwohl der Verkehr zunahm. Alle Arten von Anwendungslogik wurden in monolithische verwaltete Plattformen der einen oder anderen Art integriert. Das Prinzip, speziell entwickelte Microservices zu erstellen, ist an sich nicht gut und schien ab einem bestimmten Punkt für viele unserer Teams auch keinen positiven ROI mehr zu bringen.

Eine Microservice-Architektur kann kostspielig sein. Im letzten Jahrzehnt gab es die Meinung, dass dies eine natürliche Politik für große Ingenieursorganisationen sei, weil:

  • Teams können ihre Dienste unabhängig von der breiteren Organisation und ihrem Code iterieren
  • Kleine Komponenten der Serving-Architektur können ohne Beeinträchtigung des größeren Systems geändert werden
  • Die Architektur ermöglicht die Definition klarer, verwaltbarer Anwendungs- und Fehlerdomänen über unabhängige Dienste
  • Die Architektur ermöglicht unabhängig einstellbare oder skalierbare Workloads

Man muss die Komplexität der Arbeit berücksichtigen, die dadurch auf kleine Service-Eigentümerteams und das breitere Ökosystem verlagert wird – im Gegensatz zu einer einzelnen oder kleinen Anzahl von Monolithen. Die ausgelagerte Arbeit hängt von der Reife des Technologie-Stacks der Organisation ab; aber es kann Folgendes umfassen:

Verteilte betriebliche Verantwortlichkeiten und Gemeinkosten auf alle Service-Owner-Teams

  • Das Verständnis und die Konfiguration von Service-Infrastrukturkomponenten von Jobplanungs- und Bereitstellungstools, Service Discovery, RPC-Frameworks, VMs und zugehörigem Tuning, Service-Überwachung und -Protokollierung
  • Verteilte Definitionen und Entwicklungsprozesse für SLOs und SLIs, Dienstausfall- und Fehlerbehandlung, Gegendruckbehandlung und Fehlersignalisierung
  • Verteilte und oft unkoordinierte Kapazitätsplanung, Lasttests, Integrationstests, Implementierung und Verantwortlichkeiten
  • Die Anwendungslogik, die mit vielen Back-End-Diensten interagiert, muss häufig durch eine Reihe maßgeschneiderter Dienst-API-Definitionen, Semantiken, Datenmodelle, Versionierungssysteme und gelegentlich sogar unterschiedlicher Protokolle navigieren
  • Ingenieure müssen die gesamte Servicearchitektur und die Verkehrsmuster verstehen und überdenken, um funktionale Dinge zu entwickeln
  • Organische Problemumgehungen für suboptimale oder Engpässe bei der Bereitstellung von Pfaden, verteilte Datenreplikation und -verbrauch sowie zirkuläre Anforderungsabhängigkeiten
  • Lokalisierte Ansätze für Probleme der Inferenz und Rangfolge, der Ereignisverarbeitung, der HTTP-/internen Protokoll-API-Übersetzung und der Datenmodellzuordnung
  • Allgemeine Fragmentierung und schwierige Aufrechterhaltung von Standards im gesamten Stack

Das Problem besteht darin, dass der Prozess der Erstellung, des Aufbaus und der Operationalisierung eines neuen Dienstes teuer ist . Die Integration dieses Dienstes in die Produktionsarchitektur ist schwierig. Die Aufmerksamkeit, die erforderlich ist, um einen anderen Dienst für einen effizienten Betrieb abzustimmen ; Das Einrichten entsprechender Dienstkonten, Beobachtbarkeits- und Protokollierungsprofile, Integrationstests, die Bereitschaftsrotation und alles andere erhöht lediglich den Wartungs- und Betriebsaufwand des Teams. Den meisten Unternehmen mangelt es an Automatisierung und einem durchgängigen Gerüst für diese Art komplexer Standardarbeiten.

Dieser Mehraufwand ist ein großer Anreiz für Teams, sich an das von UNIX inspirierte Prinzip der Microservice-Architektur zu halten: „ Eine Sache gut machen “. Es ist einfach einfacher, neue Anwendungsfälle in bestehende Dienste zu integrieren. Am äußersten Ende des Spektrums betreiben Teams „Makro“-Dienste, die alles umfassen, wofür sie als Team verantwortlich sind, was eine Vielzahl von Produkten oder Fähigkeiten umfassen kann. Die Eigentumsqualität sinkt mit der Zeit, da Umstrukturierungen relativ häufig vorkommen. Du arbeitest mit einem Schlammballen.

Ausfälle von Makrodiensten sind nicht auf einen bestimmten Funktionsumfang beschränkt, sondern auf einen unvorhersehbaren oder prinzipienlosen Teil des Systems, der möglicherweise historischen Organigrammen ähnelt. Die Website toleriert möglicherweise die Nichtverfügbarkeit dieser Dienste oder auch nicht. Es ist schwieriger, Dienste für heterogene Arbeitslasten zu optimieren. Anrufpfade können nicht entwirrt werden. Ein ehemaliger Kollege prägte dafür den „Mikrolith“.

Microservices kodieren und fördern die lokale Optimierung in der Bereitstellungsarchitektur. Es ist schwierig, Teams einem prinzipiellen Design für die Bereitstellung von Architektur zur Rechenschaft zu ziehen, wenn das Ziel die Föderation der Serviceentwicklung ist. Ebenso ist es schwierig, Backend-weite Optimierungsprobleme zu lösen, wenn die Eigenschaften abhängiger Dienste maßgeschneidert sind. Ohne eine sorgfältig gestaltete Bereitstellungsarchitektur und unterstützende Serviceplattformen ist es schwierig, einen Hebel zu finden – wiederverwendbarer Produktplattformcode ist über eine Reihe großer Dienste oder gemeinsam genutzter Bibliotheken verstreut ; Die Frontend-Dienste sind in der Regel maßgeschneidert.

Die Hebelwirkung von Microservices wurde auf der Rechenebene (was auch immer die Orchestrierung und Ausführung von Servicejobs oder Containern ist), der Serviceerkennung, der VM (in bestimmten Kontexten anwendbar), dem Service-Framework (wie gRPC, Finagle oder Rest.Li ) und zentralisierten Entwicklertools gefunden . Natürlich fassen Service Meshes einige dieser Bedenken gut zusammen.

Eine andere Möglichkeit, diese Probleme anzugehen, besteht darin, den Funktionsaufwand zu reduzieren. Anstatt also zu versuchen, den wiederholten Infrastrukturaufwand für die Ausführung des Dienstes zu reduzieren , können Sie die Kosten für Teams senken, die gemeinsame Arbeitsklassen neu implementieren . Aus diesem Grund sind verwaltete Plattformen so erfolgreich – auch wenn die Erstellung oder der Betrieb eines Dienstes teuer ist, wenn wir seine Anwendungslogik durch Auslagerung auf eine öffentliche oder private verwaltete Plattform ausdünnen können, wird er für das Eigentümerteam weniger belastend.

Für Unternehmen ist es wichtig, architektonische Kompromisse sorgfältig auf der Grundlage ihrer spezifischen Bedürfnisse, Ziele und Technologie-Stack-Reife zu bewerten. Microservices bieten bestimmte Vorteile. Sie bringen auch Komplexitäten und betrieblichen Overhead mit sich, die zunächst beherrschbar erscheinen, sich aber mit der Zeit verstärken. Wenn diese Probleme nicht angegangen werden, ist der End-to-End-Entwicklungsprozess kaum einfacher als die Arbeit in einem Monolithen.

Ein paar Dinge, die Sie beachten sollten, insbesondere wenn Sie mit einem alten Mikrolith arbeiten:

  • „Große Dienste“ oder Monolithen sind nicht unbedingt schlecht; Sie erfordern eine andere Art von Tools, Infrastrukturunterstützung und andere Prinzipien als Microservices, sollten aber so aufgebaut sein, dass sie klar definierte gemeinsame Elemente der Serving-Architektur erfassen
  • Sich für den Grundsatz „Eine Aufgabe, ein Service“ einzusetzen, ist tendenziell viel weniger praktisch, als intuitive Grenzen für Bereiche enger Zusammenarbeit, Leistungsbedenken und eindeutige Fehlerbereiche zu ziehen – und Teams dazu zu drängen, sich an den Plan zu halten
  • Sie können die Komplexität und den Overhead von „zu vielen Diensten“ verringern, indem Sie entweder die vertikale Tiefe des Stacks, für den Dienstbesitzer verantwortlich sind (Dienst-Frameworks, Service Mesh, Computing), sowie die Spanne des Anwendungsraums durch verwaltete Dienste reduzieren oder Plattformen für gemeinsame Arbeitsabläufe