1
 
 
Profil
In deinem persönlichen Profilbereich kannst du den Status deiner Bewerbung einsehen, unvollständige Bewerbungen zwischenspeichern und aktuelle News und Events einsehen

Der Begriff "Architektur" bzw. "Software-Architekt" hat in der Softwareentwicklung nicht den besten Ruf. Man denkt unwillkürlich an umfangreiche Konzepte, fehlenden Pragmatismus, Elfenbeintürme, Architektur-Reviews, merkwürdige UML-Diagramme voller Halbwahrheiten, "upfront design", usw. usf. So ganz ohne Leitlinien geht es aber natürlich auch nicht.

Gerade bei einer Neuentwicklung auf der grünen Wiese hat man also eine faire Chance, es in diese oder jene Richtung komplett zu versauen. In Lhotse haben wir uns im Laufe des Projektes auf folgende Prinzipien geeinigt:

1.Makro-Architektur:

  1. Vertikaler Systemschnitt
  2. Shared Nothing
  3. RESTful Architecture
  4. Zentrale Verantwortung für Daten und Datenversorungsprozesse

2.Mikro-Architektur: 

  1. Buy when not core
  2. Gemeinsame Basistechnologien

1. Makro-ArchitektuR

    makroarchitektur-otto
    makroarchitektur-otto

    Bei der Makro-Architektur geht es um die "Architektur im Großen": Welche Teilsysteme gibt es, wie arbeiten sie zusammen und an welche Prinzipien müssen sich alle Teilsysteme und Teams halten.

    1.A) Vertikaler Systemschnitt

    Eine "klassische" Architektur teilt sich in Schichten und Module.

      schichtenarchitektur-otto
      schichtenarchitektur-otto

      Häufig spiegelt sich dass dann auch in der Team-Struktur wieder: Ein oder wenige Teams pro Layer. Diese Aufteilung ist nicht ganz unproblematisch:

      • Für viele Anforderungen muss die Arbeit mehrere Teams eng koordiniert werden weil mehrere Schichten betroffen sind.
      • Die Anzahl der Teams ist in der Regel schlecht skalierbar. Die Anzahl der Entwickler pro Team sowieso.
      • Engpässe in einzelnen, zentralen Teams werden zu einem Problem für andere Teams.
      • Die Code-Base wird sehr schnell sehr groß. Niemand durchblickt mehr das Gesamtsystem.
      • Die Teams sind durch die gemeinsame Code-Base eng verbunden. Selbst das updaten einer verwendeten Library kann zum Geduldspiel werden.

        Man könnte noch lange so weitermachen, aber hier geht es um die Lhotse-Architektur: und da haben wir uns für einen vertikalen Schnitt durch das System entschieden.

          Vertikalschnitte-otto
          Vertikalschnitte-otto

          Jedes grüne Kästchen ist eine eigenständige Anwendung mit eigener Datenhaltung und eigenem Frontend. Manche Teams haben mehr als eine "Vertikale", aber keine Vertikale wird von mehreren Teams entwickelt.

          Eigene Datenhaltung bedeutet dabei auch, dass sich Vertikalen keinen Zustand über die selbe Datenbank teilen dürfen. Eine geteilte Datenbank würde wieder eine enge Kopplung zwischen den Systemen erzeugen: sie müssten sich über das Schema der Daten einig sein.

          Der interne Aufbau einer Vertikalen liegt vollständig in der Verantwortung des Teams. Insbesondere gibt es keine gemeinsame Code-Base. Das führt zwar gelegentlich zu Parallelentwicklung, dafür müssen aber nicht die abweichenden Bedürfnisse mehrerer Teams in eine gemeinsam genutzte Library gedengelt werden.

          1.B) Shared Nothing

          Der Begriff "shared nothing" drückt aus, dass sich die Teilsysteme untereinander, aber auch die einzelnen Instanzen einer geclusterten  Vertikalen, keinen gemeinsamen Zustand in der Anwendung halten. Es gibt also keine In-Memory Caches, über die sich Cluster-Knoten miteinander unterhalten müssen, keine HTTP-Sessions, die zwischen den Instanzen repliziert werden, usw.

          Da sich einzelne Instanzen nichts teilen, müssen sie auch nicht miteinander kommunizieren und kein Load-Balancer muss Rücksicht darauf nehmen, welche "Session" auf welche Knoten geleitet werden muss (das ist u.a. bei Deployments sowie für die Ausfallsicherheit wichtig).

          Zustand in jeder Form wird also nur außerhalb des Systems gestattet: Im Browser, der Datenbank, einem Memcache oder in einem HTTP-Cache. Probleme mit der Cache-Coherency werden auf diese Weise vollständig vermieden

          1.C) RESTful Architecture

          Natürlich müssen die einzelnen Vertikalen trotz aller Eigenständigkeit miteinander kommunizieren. Außerdem gibt es den Bedarf, für beispielsweise externe Apps oder ähnliches technische Schnittstellen bereitzustellen. Und dann gibt es natürlich auch noch die Integration der Teilsysteme in eine gemeinsame Shop-GUI und die Konfiguration des Shops durch eine Backoffice-Application (aka "Shopoffice").

          Damit alle diese Dinge möglich sind, haben wir uns auf eine REST Architektur geeinigt. REST heißt dabei nicht "wir tauschen XML-Dokumente für HTTP aus und verwenden auch PUT und DELETE"; wir nehmen das etwas ernster:

          • Definierte Resourcen
          • Verwendung definierter Media-Types (falls möglich vorhandene, ansonsten Vendor-Specific)
          • Beachtung der definierten HTTP Verben, Status Codes und Header
          • Das unaussprechliche HATEOAS Prinzip (erinnert mich immer an PCMCIA - People Can't Memorize Computer-Industries Acronyms), also die Verwendung von Links bzw. "Hyermedia Controls" in den Ressourcen um die Möglichkeiten der Zustandsübergänge (das ST in REST) navigierbar zu gestalten.
          • Unterstützung von HTTP Caches.

          Unter anderem ist dabei ein Open-Source Projekt http://github.com/otto-de/jsonhome entstanden, mit dem eine Anwendung ein json-home Dokument veröffentlichen oder auch konsumieren kann.

          1.D) Daten und Datenversorung

          Da es sich bei der Anwendung um einen Online-Shop handelt, stehen die Chancen gut, dass viele Teilsysteme etwas über Produkte wissen müssen. Wenn sie aber keine gemeinsame Datenbank verwenden, wie werden dann Informationen geteilt? Dafür haben wir zwei Varianten:

          • Schaffung von Redundanzen über Datenversorgungsprozesse.
          • Ad-Hoc Anfragen über REST Schnittstelle

          Die Datenversorgung erfolgt dabei stets asynchron im Hintergrund. Kein Kunde soll auf derartige Prozesse warten müssen. Inkonsistenzen zwischen den Systemen werden dabei bewusst in Kauf genommen.

          Die Zugriffe zwischen den Systemen erfolgen dabei grundsätzlich über PULL-Mechanismen wie z.B. AtomPub Feeds da sich auf diese Weise die Kopplung zwischen den Systemen reduzieren lässt. Da wir ohnehin mit Inkonsistenzen rechnen müssen, kommt es auch nicht auf ein paar Sekunden Zeitversatz gegenüber einer Aktualisierung per PUSH an.

          Sind solche Inkonsistenzen nicht akzeptabel, dürfen Systeme ausnahmsweise auch Ad-Hoc Anfragen an andere Vertikalen stellen; das versuchen wir jedoch zu vermeiden, da es eine enge Kopplung der Systeme mit sich bringt.

          Der Kern des Architektur-Prinzips ist jedoch, dass für alle Daten nur eine Vertikale führend ist. Alle anderen Systeme greifen nur über REST-Schnittstellen auf die führende Vertikale zu und halten sich bei Bedarf redundante Daten. Die "Wahrheit" über ein Datum liegt in der Hand des führenden Systems.

          2. Mikro-Architektur

          Im Gegensatz zur Makro-Architektur geht es bei der Mikro-Architektur um die "Architektur im Kleinen", also die der einzelnen Vertikalen.

            mikroarchitektur-otto
            mikroarchitektur-otto

            Da die Hoheit über die Vertikalen in der Verantwortung der zuständigen Teams liegen, gibt es hier keine übergreifenden Richtlinien. Es ist nicht vorgeschrieben, welche Frameworks verwendet werden müssen oder wie die Struktur der Anwendung auszusehen hat. Nur ein paar flankierende Absprachen.

            2.A) Buy when non core

            Wir sehen unsere Kernkompetenz nicht darin, beispielsweise eine eigene Datenbank oder eigene Frontend-Frameworks zu entwickeln. Stattdessen bedienen wir uns hier am Markt und kaufen entweder Dinge ein oder verwenden schlicht ein "Produkt" aus dem Open-Source Umfeld. Was genau als "Core" definiert ist, liegt dagegen wieder in der Entscheidung des Teams.

            2.B) Gemeinsame Basistechnologien

            Zur Zeit verwenden alle Teams die MongoDB als DBMS. Im Prinzip könnte eine Vertikale sich auch für eine andere Persistenzlösung entscheiden. Allerdings würde das betriebliche Aufwände nach sich ziehen, weshalb wir solche Änderungen vermeiden wollen.

            Es gibt noch einige weniger weitere Dinge wie Tomcat als Servlet-Container oder auch gemeinsam genutzte Monitoring-Werkzeuge, die zur Zeit in allen Teams ähnlich verwendet werden, grundsätzlich aber als Bestandteil der Mikro-Architektur definiert sind. Die Teams könnten sich also gegen solche Grundlagen entscheiden, sind aber dazu angehalten, vorher in den Ring zu steigen und ihr Vorhaben in "großer Runde" durchzuboxen.

            Anfangs haben wir auch noch eine "common" Library entwickelt und teamübergreifend genutzt. Mittlerweile sind wir jedoch zu dem Schluss gekommen, dass die Nachteile einer solchen Bibliothek (hinterrücks werden wieder Abhängigkeiten zu 3rd-Party Libraries eingeführt) dir Vorteile überwiegen.

            Was viel besser funktioniert:

            "Wenn es Code gibt, den sich Teams teilen wollen, entwickelt es als Open-Source Projekt, veröffentlicht es auf GitHub und behandelt es wie eine 3rd-Party Dependency".

            Bisher sind auf diese Weise drei GitHub Projekte http://github.com/otto-de entstanden:

            • hmac-auth: zwei Libraries (client, server) für die HMAC-Authentication + Authorization beim Zugriff auf REST Ressourcen.
            • jsonhome: Libraries zum publizieren und konsumieren von json-home Dokumenten.
            • wickettester: Unit-Testing für Wicket-basierte Web Applications.

            Zwei weitere sind in Vorbereitung:

            • mongo-migrations: Tools für die on-the-fly Migration von MongoDB Dokumenten.
            • job-execution-framework: Ein Framework für die Steuerung, Ausführung und Kontrolle von asynchron laufenden Jobs.

            0Noch keine Kommentare

            Dein Kommentar
            Antwort auf:  Direkt auf das Thema antworten

            Geschrieben von

            Guido Steinacker
            Guido Steinacker
            Executive Software Architect

            Ähnliche Beiträge

            We want to improve out content with your feedback.

            How interesting is this blogpost?

            We have received your feedback.

            Cookies erlauben?

            OTTO und drei Partner brauchen deine Einwilligung (Klick auf "OK") bei einzelnen Datennutzungen, um Informationen auf einem Gerät zu speichern und/oder abzurufen (IP-Adresse, Nutzer-ID, Browser-Informationen).
            Die Datennutzung erfolgt für personalisierte Anzeigen und Inhalte, Anzeigen- und Inhaltsmessungen sowie um Erkenntnisse über Zielgruppen und Produktentwicklungen zu gewinnen. Mehr Infos zur Einwilligung gibt’s jederzeit hier. Mit Klick auf den Link "Cookies ablehnen" kannst du deine Einwilligung jederzeit ablehnen.

            Datennutzungen

            OTTO arbeitet mit Partnern zusammen, die von deinem Endgerät abgerufene Daten (Trackingdaten) auch zu eigenen Zwecken (z.B. Profilbildungen) / zu Zwecken Dritter verarbeiten. Vor diesem Hintergrund erfordert nicht nur die Erhebung der Trackingdaten, sondern auch deren Weiterverarbeitung durch diese Anbieter einer Einwilligung. Die Trackingdaten werden erst dann erhoben, wenn du auf den in dem Banner auf otto.de wiedergebenden Button „OK” klickst. Bei den Partnern handelt es sich um die folgenden Unternehmen:
            Google Inc., Meta Platforms Ireland Limited, elbwalker GmbH
            Weitere Informationen zu den Datenverarbeitungen durch diese Partner findest du in der Datenschutzerklärung auf otto.de/jobs. Die Informationen sind außerdem über einen Link in dem Banner abrufbar.