Expertise · Komplexe Architekturen
Mehrere Systeme, die zusammen funktionieren müssen, auch wenn eines davon ausfällt.
Wir entwerfen und betreiben Plattformen aus mehreren Diensten, mit Message-Bus, begrenzten Wiederholungen, Idempotenz-Schlüsseln, Circuit Breakern und Veröffentlichung mit automatischer Rückkehr. Jedes der folgenden Muster läuft in einem eigenen System, nicht in einem Diagramm.
Bereits gebautWir betreiben vier eigene Plattformen mit unterschiedlichen Architekturen und können alle öffnen. Die Zahlen sind heute mit Befehlen gemessen, nicht aus der Dokumentation übernommen: aichat hat 28 Dienstverzeichnisse, 235 Datenmodelle auf vier Schemata und einen Nachrichtenbus mit 297 Queues und 17.525 Verknüpfungen; Kallina hat 472 Edge-Funktionen, 559 Migrationen und 28 geplante Aufgaben in der Datenbank; MEGA CRM hat ein Backend von 9.516 Zeilen mit 99 Routen und 179 Zugriffsrichtlinien pro Zeile; Taskin läuft 21 geplante Aufgaben ohne irgendein Docker. Die von uns genannte Einschränkung: An zwei Stellen ist die eigene Dokumentation dem Code hinterherhinkt — eine Aussage über die Zeilenzahl war um 16% veraltet, und ein Infrastrukturdiagramm beschrieb einen Server, auf dem wir nichts mehr betreiben. Wir haben die Messung verwendet, nicht das Dokument.
„Komplexe Architektur“ bedeutet nicht viele Kästen auf einer Zeichnung. Es bedeutet, dass Sie wissen, was passiert, wenn einer davon nicht antwortet. Ein System mit drei Diensten, die synchron aufgerufen werden, ohne Wiederholungsgrenze und ohne Idempotenz, ist fragiler als ein Monolith — denn jede neue Verbindung ist eine neue Fehlerart, und Fehlerarten vermehren sich schneller als Funktionen.
Unsere Arbeit beginnt mit der Trennung von Verantwortlichkeiten und endet bei dem, was sichtbar wird, wenn etwas ausfällt. In einer der eigenen Plattformen laufen Nachrichten nicht direkt zwischen Diensten, sondern über einen Nachrichtenbus mit 297 Warteschlangen, 9 Exchanges und 17.525 Verbindungen, davon 278 pro Kunde generierte Warteschlangen, nicht von Hand geschrieben. Acht Warteschlangen haben einen Dead-Letter-Exchange und acht eine Message-TTL von fünf Minuten — das heißt, eine Nachricht, die nicht verarbeitet werden kann, landet irgendwo, wo sie gesehen werden kann, und verschwindet nicht.
Die Muster, die wir einsetzen, sind wenige und wiederholen sich: Wiederholungen mit im Code festgelegter Obergrenze, Idempotenzschlüssel, die eine zweite Zustellung desselben Ereignisses harmlos machen, ein Unterbrecher, der Aufrufe zu einem wiederholt ausfallenden Dienst stoppt, eine Verbrauchsgrenze vor kostenpflichtigen Aktionen und Alarme mit Wiederholschwelle, damit ein intermittierender Fehler nicht den Rest begräbt.
Der letzte Teil, der oft übersehen wird: die Veröffentlichung. Eine der Plattformen wird per Dateisynchronisierung veröffentlicht, ohne Docker, mit der Prüfung, dass die bereitgestellte Seite genau den Kennzeichner des gerade veröffentlichten Pakets enthält — nicht nur, dass der Server 200 zurückgibt — und mit automatischer Rückkehr zur vorherigen Version, wenn die Prüfung fehlschlägt. Die Regel entstand nach einem echten Vorfall, bei dem eine oberflächliche Prüfung eine gute Veröffentlichung aufgehoben hat.