Softwarearchitektur und Systemdesign: Das Gesamtbild und der Ressourcenleitfaden

Hallo Kollegen.

Heute bieten wir Ihnen eine Übersetzung eines Artikels von Tugberk Ugurlu an, der sich vorgenommen hat, in einem relativ kleinen Band die Prinzipien des Entwurfs moderner Softwaresysteme zu skizzieren. Das sagt der Autor zusammenfassend über sich selbst:

Softwarearchitektur und Systemdesign: Das Gesamtbild und der Ressourcenleitfaden
Da es absolut unmöglich ist, in einem Habro-Artikel ein so kolossales Thema wie Architekturmuster + Designmuster aus dem Jahr 2019 abzudecken, empfehlen wir nicht nur den Text von Herrn Uruglu selbst, sondern auch die zahlreichen Links, die er freundlicherweise darin eingefügt hat. Wenn es Ihnen gefällt, veröffentlichen wir einen höher spezialisierten Text über den Entwurf verteilter Systeme.

Softwarearchitektur und Systemdesign: Das Gesamtbild und der Ressourcenleitfaden

Foto Isaac Smith von Unsplash

Wenn Sie noch nie mit der Herausforderung konfrontiert waren, ein Softwaresystem von Grund auf neu zu entwerfen, ist es zu Beginn einer solchen Arbeit manchmal nicht einmal klar, wo Sie anfangen sollen. Ich glaube, dass man zunächst Grenzen ziehen muss, damit man eine mehr oder weniger sichere Vorstellung davon hat, was genau man entwerfen möchte, und dann die Ärmel hochkrempeln und innerhalb dieser Grenzen arbeiten muss. Als Ausgangspunkt können Sie ein Produkt oder eine Dienstleistung nehmen (idealerweise eines, das Ihnen wirklich gefällt) und überlegen, wie Sie es umsetzen können. Sie werden überrascht sein, wie einfach dieses Produkt aussieht und wie viel Komplexität es tatsächlich beinhaltet. Nicht vergessen: einfach – meist komplex, und das ist in Ordnung.

Ich denke, der beste Rat, den ich jedem geben kann, der mit dem Entwurf eines Systems beginnt, ist dieser: Machen Sie keine Annahmen! Von Anfang an müssen Sie die über dieses System bekannten Fakten und die damit verbundenen Erwartungen spezifizieren. Hier sind einige gute Fragen, die Sie stellen sollten, um Ihnen den Einstieg in Ihr Design zu erleichtern:

  • Welches Problem versuchen wir zu lösen?
  • Wie viele Benutzer interagieren maximal mit unserem System?
  • Welche Muster zum Schreiben und Lesen von Daten werden wir verwenden?
  • Welche Fehlerfälle sind zu erwarten, wie gehen wir damit um?
  • Was sind die Erwartungen an die Systemkonsistenz und -verfügbarkeit?
  • Müssen Sie bei Ihrer Arbeit irgendwelche Anforderungen im Zusammenhang mit der externen Überprüfung und Regulierung berücksichtigen?
  • Welche Arten sensibler Daten werden wir speichern?

Dies sind nur einige Fragen, die sowohl mir als auch den Teams, in denen ich im Laufe der Jahre meiner beruflichen Tätigkeit mitgewirkt habe, von Nutzen waren. Wenn Sie die Antworten auf diese Fragen kennen (und alle anderen, die für den Kontext, in dem Sie arbeiten müssen, relevant sind), können Sie sich nach und nach mit den technischen Details des Problems befassen.

Legen Sie den Anfangspegel fest

Was meine ich hier mit „Grundlinie“? Tatsächlich „können“ heutzutage die meisten Probleme in der Softwareindustrie mit vorhandenen Methoden und Technologien gelöst werden. Dementsprechend verschaffen Sie sich durch die Navigation in dieser Landschaft einen gewissen Vorsprung, wenn Sie mit Problemen konfrontiert werden, die jemand anderes vor Ihnen lösen musste. Vergessen Sie nicht, dass Programme geschrieben werden, um Geschäfts- und Benutzerprobleme zu lösen. Deshalb bemühen wir uns, das Problem auf die unkomplizierteste und einfachste Weise (aus Sicht des Benutzers) zu lösen. Warum ist es wichtig, sich daran zu erinnern? Vielleicht suchen Sie in Ihrem Koordinatensystem gerne nach einzigartigen Lösungen für alle Probleme, weil Sie denken: „Was für ein Programmierer bin ich, wenn ich überall Mustern folge“? Tatsächlich, Die Kunst hier besteht darin, Entscheidungen darüber zu treffen, wo und was zu tun ist. Natürlich hat jeder von uns von Zeit zu Zeit mit einzigartigen Problemen zu kämpfen, die jeweils eine echte Herausforderung darstellen. Wenn jedoch unser Ausgangsniveau klar definiert ist, wissen wir, wofür wir unsere Energie aufwenden müssen: nach vorgefertigten Optionen zur Lösung des vor uns liegenden Problems suchen oder es weiter studieren und ein tieferes Verständnis erlangen.

Ich glaube, ich konnte Sie davon überzeugen, dass, wenn ein Spezialist sicher versteht, was die architektonische Komponente einiger wunderbarer Softwaresysteme ist, dieses Wissen unerlässlich ist, um die Kunst eines Architekten zu beherrschen und eine solide Grundlage in diesem Bereich zu entwickeln.

Okay, wo also anfangen? U Donna Martina Auf GitHub gibt es ein Repository namens Systemdesign-Grundierung, in dem Sie lernen können, wie man Großsysteme entwirft, und sich auf Interviews zu diesem Thema vorbereiten können. Das Repository verfügt über einen Abschnitt mit Beispielen echte ArchitekturenDabei wird insbesondere berücksichtigt, wie sie an die Gestaltung ihrer Systeme herangehen einige bekannte Unternehmenz. B. Twitter, Uber usw.

Bevor wir jedoch zu diesem Material übergehen, werfen wir einen genaueren Blick auf die wichtigsten architektonischen Herausforderungen, denen wir in der Praxis gegenüberstehen. Dies ist wichtig, da Sie VIELE Aspekte eines hartnäckigen und vielschichtigen Problems spezifizieren und es dann im Rahmen der in einem bestimmten System geltenden Vorschriften lösen müssen. Jackson Gabbard, ein ehemaliger Facebook-Mitarbeiter, schrieb 50-minütiges Video über Systemdesign-Interviews, wo er seine eigenen Erfahrungen bei der Prüfung Hunderter Bewerber teilte. Während sich das Video stark auf den Entwurf großer Systeme und die Erfolgskriterien konzentriert, die bei der Suche nach einem Kandidaten für eine solche Position wichtig sind, dient es dennoch als umfassende Informationsquelle zu den Dingen, die beim Entwurf von Systemen am wichtigsten sind. Ich schlage auch vor Zusammenfassung Dieses Video.

Bauen Sie Kenntnisse über das Speichern und Abrufen von Daten auf

Normalerweise hat Ihre Entscheidung darüber, wie Sie Ihre Daten langfristig speichern und abrufen, einen entscheidenden Einfluss auf die Systemleistung. Daher müssen Sie zunächst die erwarteten Schreib- und Leseeigenschaften Ihres Systems verstehen. Dann müssen Sie in der Lage sein, diese Indikatoren zu bewerten und auf der Grundlage der durchgeführten Bewertungen Entscheidungen zu treffen. Sie können diese Arbeit jedoch nur effektiv bewältigen, wenn Sie die vorhandenen Datenspeichermuster verstehen. Dies setzt grundsätzlich fundierte Kenntnisse in Bezug auf Folgendes voraus Datenbankauswahl.

Datenbanken können als Datenstrukturen betrachtet werden, die äußerst skalierbar und langlebig sind. Daher sollten Kenntnisse über Datenstrukturen für Sie bei der Auswahl einer bestimmten Datenbank von großem Nutzen sein. Zum Beispiel, Redis ist ein Datenstrukturserver, der verschiedene Arten von Werten unterstützt. Es ermöglicht Ihnen, mit Datenstrukturen wie Listen und Mengen zu arbeiten und Daten mithilfe bekannter Algorithmen zu lesen, z. B. LRU, Organisation solcher Arbeiten in einem dauerhaften und leicht zugänglichen Stil.

Softwarearchitektur und Systemdesign: Das Gesamtbild und der Ressourcenleitfaden

Foto Samuel Zeller von Unsplash

Sobald Sie die verschiedenen Datenspeichermuster ausreichend verstanden haben, können Sie mit der Untersuchung der Datenkonsistenz und -verfügbarkeit fortfahren. Zunächst einmal müssen Sie verstehen CAP-Theorem zumindest im Allgemeinen, und dieses Wissen dann durch einen genaueren Blick auf etablierte Muster zu verfeinern Konsistenz и Verfügbarkeit. Auf diese Weise entwickeln Sie ein Verständnis für das Fachgebiet und verstehen, dass das Lesen und Schreiben von Daten eigentlich zwei sehr unterschiedliche Probleme sind, die jeweils ihre eigenen, einzigartigen Herausforderungen mit sich bringen. Mit einigen Konsistenz- und Verfügbarkeitsmustern können Sie die Systemleistung erheblich steigern und gleichzeitig einen reibungslosen Datenfluss zu Ihren Anwendungen gewährleisten.

Zum Abschluss des Gesprächs über Datenspeicherprobleme sollten wir noch das Caching erwähnen. Soll es gleichzeitig auf dem Client und dem Server laufen? Welche Daten werden in Ihrem Cache sein? Und warum? Wie organisieren Sie die Cache-Ungültigmachung? Wird es regelmäßig und in bestimmten Abständen durchgeführt? Wenn ja, wie oft? Ich empfehle, mit dem Studium dieser Themen zu beginnen nächsten Abschnitt die oben genannte Systemdesign-Grundierung.

Kommunikationsmuster

Systeme bestehen aus verschiedenen Komponenten; Dies können verschiedene Prozesse sein, die innerhalb desselben physischen Knotens ausgeführt werden, oder verschiedene Maschinen, die in verschiedenen Teilen Ihres Netzwerks ausgeführt werden. Einige dieser Ressourcen in Ihrem Netzwerk sind möglicherweise privat, andere sollten jedoch öffentlich und für Verbraucher zugänglich sein, die von außerhalb darauf zugreifen.

Es gilt, die Kommunikation dieser Ressourcen untereinander sowie den Informationsaustausch zwischen dem gesamten System und der Außenwelt sicherzustellen. Im Kontext des Systemdesigns stehen wir auch hier vor einer Reihe neuer und einzigartiger Herausforderungen. Mal sehen, wie sie nützlich sein können asynchrone Aufgabenflüsse, und was pEs stehen verschiedene Kommunikationsmuster zur Verfügung.

Softwarearchitektur und Systemdesign: Das Gesamtbild und der Ressourcenleitfaden

Foto Tony Stoddard von Unsplash

Bei der Organisation der Kommunikation mit der Außenwelt ist dies immer sehr wichtig Sicherheit, deren Bereitstellung ebenfalls ernst genommen und aktiv vorangetrieben werden muss.

Verbindungsverteilung

Ich bin mir nicht sicher, ob die Unterbringung dieses Themas in einem separaten Abschnitt für alle gerechtfertigt erscheint. Dennoch werde ich dieses Konzept hier ausführlich vorstellen und glaube, dass der Stoff in diesem Abschnitt am treffendsten durch den Begriff „Verbindungsverteilung“ beschrieben wird.

Systeme entstehen durch die richtige Verbindung vieler Komponenten und ihre Kommunikation untereinander wird oft auf Basis etablierter Protokolle, zum Beispiel TCP und UDP, organisiert. Allerdings reichen diese Protokolle als solche oft nicht aus, um alle Anforderungen moderner Systeme zu erfüllen, die häufig unter hoher Last betrieben werden und zudem stark von den Benutzerbedürfnissen abhängig sind. Oft ist es notwendig, Möglichkeiten zur Verteilung der Verbindungen zu finden, um solch hohe Belastungen des Systems bewältigen zu können.

Diese Verteilung basiert auf dem Bekannten Domain-Name-System (DNS). Ein solches System ermöglicht Domänennamentransformationen wie gewichtete Round-Robin- und latenzbasierte Methoden, um die Lastverteilung zu unterstützen.

Lastverteilung ist von grundlegender Bedeutung, und praktisch jedes große Internetsystem, mit dem wir heute zu tun haben, befindet sich hinter einem oder mehreren Load Balancern. Load Balancer helfen dabei, Clientanfragen auf mehrere verfügbare Instanzen zu verteilen. Load Balancer gibt es sowohl in Hardware als auch in Software, in der Praxis muss man sich jedoch beispielsweise häufiger mit Software-Modellen befassen HAProxy и ELB. Reverse-Proxys konzeptionell auch sehr ähnlich zu Load Balancern, obwohl es einen Bereich zwischen dem ersten und dem zweiten gibt deutliche Unterschiede. Diese Unterschiede müssen bei der Gestaltung eines Systems entsprechend Ihren Anforderungen berücksichtigt werden.

Das solltest du auch wissen Content-Delivery-Netzwerke (CDN). Ein CDN ist ein globales verteiltes Netzwerk von Proxyservern, das Informationen von Knoten liefert, die geografisch näher an einem bestimmten Benutzer liegen. CDNs sind vorzuziehen, wenn Sie mit statischen Dateien arbeiten, die in JavaScript, CSS und HTML geschrieben sind. Darüber hinaus sind heute Cloud-Dienste üblich, die Verkehrsmanager bereitstellen, beispielsweise Azure Traffic ManagerDadurch erhalten Sie eine globale Verteilung und eine geringere Latenz bei der Arbeit mit dynamischen Inhalten. Allerdings sind solche Dienste in der Regel dann nützlich, wenn Sie mit zustandslosen Webdiensten arbeiten müssen.

Lassen Sie uns über Geschäftslogik sprechen. Strukturierung von Geschäftslogik, Aufgabenabläufen und Komponenten

So ist es uns gelungen, verschiedene infrastrukturelle Aspekte des Systems zu besprechen. Höchstwahrscheinlich denkt der Benutzer nicht einmal an all diese Elemente Ihres Systems und kümmert sich, ehrlich gesagt, überhaupt nicht um sie. Der Benutzer interessiert sich dafür, wie es ist, mit Ihrem System zu interagieren, was dadurch erreicht werden kann und wie das System Benutzerbefehle ausführt, was und wie es mit Benutzerdaten umgeht.

Wie der Titel dieses Artikels vermuten lässt, wollte ich über Softwarearchitektur und Systemdesign sprechen. Dementsprechend hatte ich nicht vor, Software-Entwurfsmuster zu behandeln, die beschreiben, wie Softwarekomponenten erstellt werden. Je mehr ich jedoch darüber nachdenke, desto mehr kommt es mir vor, dass die Grenze zwischen Software-Entwurfsmustern und Architekturmustern sehr verschwommen ist und die beiden Konzepte eng miteinander verbunden sind. Nehmen wir zum Beispiel Veranstaltungsanmeldung (Event-Sourcing). Sobald Sie dieses Architekturmuster übernehmen, wirkt es sich auf nahezu jeden Aspekt Ihres Systems aus: die langfristige Speicherung von Daten, den in Ihrem System angenommenen Konsistenzgrad, die Form der darin enthaltenen Komponenten usw. usw. Daher habe ich beschlossen, einige Architekturmuster zu erwähnen, die sich direkt auf die Geschäftslogik beziehen. Auch wenn sich dieser Artikel auf eine einfache Liste beschränken muss, empfehle ich Ihnen, sich damit vertraut zu machen und über die Ideen nachzudenken, die mit diesen Mustern verbunden sind. Hier bitte:

Kollaborative Ansätze

Es ist äußerst unwahrscheinlich, dass Sie in einem Projekt als Teilnehmer allein für den Systemdesignprozess verantwortlich sind. Im Gegenteil, Sie werden höchstwahrscheinlich mit Kollegen interagieren müssen, die sowohl innerhalb als auch außerhalb Ihrer Aufgabe arbeiten. In diesem Fall müssen Sie möglicherweise die ausgewählten Technologielösungen mit Kollegen bewerten, Geschäftsanforderungen ermitteln und verstehen, wie Aufgaben am besten parallelisiert werden können.

Softwarearchitektur und Systemdesign: Das Gesamtbild und der Ressourcenleitfaden

Foto Kaleidiko von Unsplash

Der erste Schritt besteht darin, ein genaues und gemeinsames Verständnis davon zu entwickeln, was das Geschäftsziel ist, das Sie erreichen möchten, und mit welchen beweglichen Teilen Sie sich befassen müssen. Insbesondere Gruppenmodellierungstechniken stürmische Ereignisse (Event Storming) tragen dazu bei, diesen Prozess deutlich zu beschleunigen und Ihre Erfolgschancen zu erhöhen. Diese Arbeit kann vor oder nach der Gliederung erfolgen Grenzen Ihrer Dienstleistungen, und vertiefen Sie es dann, wenn das Produkt reift. Basierend auf dem Grad der Konsistenz, der hier erreicht wird, können Sie auch formulieren gemeinsame Sprache für den begrenzten Kontext, in dem Sie arbeiten. Wenn Sie über die Architektur Ihres Systems sprechen müssen, ist dies möglicherweise hilfreich Modell C4, vorgeschlagen Simon Brown, insbesondere wenn Sie verstehen müssen, wie sehr Sie auf die Details des Problems eingehen und die Dinge visualisieren müssen, die Sie kommunizieren möchten.

Zu diesem Thema gibt es wahrscheinlich eine andere ausgereifte Technologie, die nicht weniger nützlich ist als Domain Driven Design. Irgendwie kehren wir jedoch zum Verständnis des Themenbereichs zurück, also zu Wissen und Erfahrung auf diesem Gebiet Domänengesteuertes Design sollte für Sie nützlich sein.

Source: habr.com

Kommentar hinzufügen