1984 veröffentlichten Rob Pike und Brian W. Kernighan einen Artikel mit dem Titel „Program Design in the Unix Environment“ im AT&T Bell Laboratories Technical Journal, in dem sie die Unix-Philosophie am Beispiel von BSDs cat -v
Kommt Ihnen das bekannt vor?
Ja, das dachte ich mir. Das ist so ziemlich die Definition von Mikrodiensten, die von James Lewis und Martin Fowler angeboten werden:
Kurz gesagt, der Microservice-Architekturstil ist ein Ansatz zur Entwicklung einer einzelnen Anwendung als Suite kleiner Services, die jeweils in einem eigenen Prozess ausgeführt werden und mit einfachen Mechanismen kommunizieren, häufig einer HTTP-Ressourcen-API.
Auch wenn ein *nix-Programm oder ein Microservice für sich genommen sehr begrenzt oder nicht einmal sehr interessant sein kann, zeigt erst die Kombination solcher unabhängig voneinander arbeitenden Einheiten ihren wahren Nutzen und damit ihre Macht.
*nix vs. microservices
Die folgende Tabelle vergleicht Programme (wie cat oder lsof ) in einer *nix-Umgebung gegen Programme in einer Microservices-Umgebung.
*nix | Microservices | |
---|---|---|
Ausführungseinheit | Programm mit stdin /stdout | Dienst mit HTTP- oder gRPC-API |
Datenfluss | Rohre | ? |
Konfiguration &Parametrierung | Befehlszeilenargumente, Umgebungsvariablen, Konfigurationsdateien | JSON/YAML-Dokumente |
Entdeckung | Paketmanager, Mann, Marke | DNS, Umgebungsvariablen, OpenAPI |
Sehen wir uns jede Zeile etwas detaillierter an.
Ausführungseinheit
Mehr zu Microservices
- Microservices-Spickzettel
- So erklären Sie Ihrem CEO Microservices
- Kostenloses eBook:Microservices vs. serviceorientierte Architektur
- Kostenloser Online-Kurs:Entwicklung cloudnativer Anwendungen mit Microservices-Architekturen
- Neueste Microservices-Artikel
Die Ausführungseinheit in *nix (z. B. Linux) ist eine ausführbare Datei (binäres oder interpretiertes Skript), die idealerweise Eingaben von stdin liest und schreibt die Ausgabe nach stdout . Ein Microservices-Setup befasst sich mit einem Dienst, der eine oder mehrere Kommunikationsschnittstellen wie HTTP- oder gRPC-APIs verfügbar macht. In beiden Fällen finden Sie zustandslose Beispiele (im Wesentlichen ein rein funktionales Verhalten) und zustandsbehaftete Beispiele, bei denen zusätzlich zur Eingabe ein interner (dauerhafter) Zustand entscheidet, was passiert.
Datenfluss
Traditionell konnten *nix-Programme über Pipes kommunizieren. Mit anderen Worten, dank Doug McIlroy müssen Sie keine temporären Dateien erstellen, die Sie weitergeben können, und jede kann praktisch endlose Datenströme zwischen Prozessen verarbeiten. Meines Wissens nach gibt es außer meinem kleinen Apache Kafka-basierten Experiment aus dem Jahr 2017 nichts Vergleichbares zu einer in Microservices standardisierten Pipe.
Konfiguration und Parametrierung
Wie konfigurieren Sie ein Programm oder einen Dienst – entweder dauerhaft oder auf Abruf? Nun, mit *nix-Programmen haben Sie im Wesentlichen drei Optionen:Befehlszeilenargumente, Umgebungsvariablen oder vollständige Konfigurationsdateien. Bei Microservices beschäftigen Sie sich normalerweise mit YAML- (oder noch schlimmer, JSON-) Dokumenten und definieren das Layout und die Konfiguration eines einzelnen Microservice sowie Abhängigkeiten und Kommunikations-, Speicher- und Laufzeiteinstellungen. Beispiele sind Kubernetes-Ressourcendefinitionen, Nomad-Jobspezifikationen oder Docker-Compose-Dateien. Diese können parametrisiert sein oder nicht; Das heißt, entweder haben Sie eine Templating-Sprache wie Helm in Kubernetes oder Sie machen sehr viel sed -i Befehle.
Entdeckung
Woher wissen Sie, welche Programme oder Dienste verfügbar sind und wie sie verwendet werden sollen? Nun, in *nix haben Sie normalerweise einen Paketmanager sowie einen guten alten Mann; zusammen sollten sie in der Lage sein, alle Fragen zu beantworten, die Sie haben könnten. In einem Microservices-Setup gibt es etwas mehr Automatisierung bei der Suche nach einem Service. Neben maßgeschneiderten Ansätzen wie SmartStack von Airbnb oder Eureka von Netflix gibt es in der Regel auf Umgebungsvariablen oder DNS basierende Ansätze, mit denen Sie Dienste dynamisch erkennen können. Ebenso wichtig ist, dass OpenAPI einen De-facto-Standard für HTTP-API-Dokumentation und -Design bietet, und gRPC tut dasselbe für enger gekoppelte Hochleistungsfälle. Berücksichtigen Sie nicht zuletzt die Entwicklererfahrung (DX), beginnend mit dem Schreiben guter Makefiles und endend mit dem Schreiben Ihrer Dokumente mit (oder in?) Stil .
Vor- und Nachteile
Sowohl *nix als auch Microservices bieten eine Reihe von Herausforderungen und Chancen
Zusammensetzbarkeit
Es ist schwer, etwas zu entwerfen, das einen klaren, scharfen Fokus hat und auch gut mit anderen spielen kann. Es ist sogar noch schwieriger, es über verschiedene Versionen hinweg richtig zu machen und entsprechende Funktionen zur Behandlung von Fehlerfällen einzuführen. Bei Microservices könnte dies Wiederholungslogik und Zeitüberschreitungen bedeuten – vielleicht ist es eine bessere Option, diese Funktionen in ein Service Mesh auszulagern? Es ist schwer, aber wenn Sie es richtig machen, kann seine Wiederverwendbarkeit enorm sein.
Beobachtbarkeit
Bei einem Monolithen (2018) oder einem großen Programm, das versucht, alles zu tun (1984), ist es ziemlich einfach, den Schuldigen zu finden, wenn die Dinge schief gehen. Aber in einem
yes | tr \\n x | head -c 450m | grep n
oder ein Anforderungspfad in einem Microservices-Setup, das beispielsweise 20 Services umfasst, wie fängst du überhaupt an um herauszufinden, wer sich schlecht benimmt? Glücklicherweise haben wir Standards, insbesondere OpenCensus und OpenTracing. Die Beobachtbarkeit könnte immer noch der größte Einzelblocker sein, wenn Sie auf Microservices umsteigen möchten.
Globaler Zustand
Während es für *nix-Programme kein so großes Problem sein mag, bleibt der globale Zustand bei Microservices eine Art Diskussion. Nämlich, wie man sicherstellt, dass der lokale (persistente) Zustand effektiv verwaltet wird und wie man den globalen Zustand mit so wenig Aufwand wie möglich konsistent macht.
Abschluss
Am Ende bleibt die Frage:Verwenden Sie das richtige Tool für eine bestimmte Aufgabe? Das heißt, genauso wie ein spezialisiertes *nix-Programm, das eine Reihe von Funktionen implementiert, für bestimmte Anwendungsfälle oder Phasen die bessere Wahl sein könnte, könnte es sein, dass ein Monolith die beste Option für Ihre Organisation oder Workload ist. Unabhängig davon hoffe ich, dass dieser Artikel Ihnen dabei hilft, die vielen starken Parallelen zwischen der Unix-Philosophie und Microservices zu erkennen – vielleicht können wir etwas von Ersterem lernen, um Letzteren zu nutzen.