1
 
 
Account
In your account you can view the status of your application, save incomplete applications and view current news and events
April 15, 2013

Architecture principles

The term "architecture" or "software architect" does not have the best reputation in software development. One involuntarily thinks of extensive concepts, lack of pragmatism, ivory towers, architecture reviews, strange UML diagrams full of half-truths, "upfront design", and so on. But of course it is not possible to do without guidelines.

So especially with a greenfield development you have a fair chance to completely screw it up in this or that direction. In Lhotse, we agreed on the following principles during the course of the project:

1.Macro architecture:

  1. Vertical system cut
  2. Shared Nothing
  3. RESTful Architecture
  4. Central responsibility for data and data supply processes

2.Micro-Architecture:

  1. Buy when not core
  2. Common base technologies

1. macro-ArchitectuR

makroarchitektur-otto
makroarchitektur-otto

Macro-architecture is about the "architecture on a large scale": what subsystems exist, how do they work together, and what principles must all subsystems and teams adhere to.

1.A) Vertical system section

A "classic" architecture divides into layers and modules.

schichtenarchitektur-otto
schichtenarchitektur-otto

This is often reflected in the team structure: one or a few teams per layer. This division is not entirely unproblematic:

  • For many requirements, the work of several teams must be closely coordinated because several layers are affected.
  • The number of teams is usually difficult to scale. The number of developers per team anyway.
  • Bottlenecks in single, central teams become a problem for other teams.
  • The code base becomes very large very quickly. No one can see through the overall system anymore.
  • The teams are closely linked by the common code base. Even updating a library in use can become a game of patience.

One could go on like this for a long time, but this is about the Lhotse architecture: and there we have decided on a vertical cut through the system.

Vertikalschnitte-otto
Vertikalschnitte-otto

Each green box is a standalone application with its own data management and front end. Some teams have more than one "vertical", but no vertical is developed by multiple teams.

Having their own data storage also means that verticals are not allowed to share state over the same database. A shared database would again create a tight coupling between the systems: they would have to agree on the schema of the data.

The internal construction of a vertical is entirely the responsibility of the team. In particular, there is no common code base. While this occasionally leads to parallel development, it does not require the divergent needs of multiple teams to be bottlenecked into a shared library.

1.B) Shared Nothing

The term "shared nothing" expresses that the subsystems among themselves, but also the individual instances of a clustered vertical, do not share a common state in the application. Thus, there are no in-memory caches that cluster nodes need to talk to each other about, no HTTP sessions that are replicated between instances, etc.

Since individual instances don't share anything, they don't need to communicate with each other, and no load balancer needs to take into account which "session" needs to be routed to which nodes (this is important for deployments, among other things, as well as for resiliency).

State in any form is therefore only allowed outside the system: In the browser, the database, a memcache, or in an HTTP cache. Problems with cache coherency are completely avoided in this way.

1.C) RESTful Architecture

Of course, the individual verticals must communicate with each other despite all their independence. There is also the need to provide technical interfaces for, say, external apps or the like. And then, of course, there is the integration of the subsystems into a common store GUI and the configuration of the store by a back-office application (aka "shopoffice").

To make all these things possible, we agreed on a REST architecture. REST doesn't mean "we exchange XML documents for HTTP and also use PUT and DELETE"; we take it a bit more seriously:

  • Defined resources
  • Use of defined Media-Types (if possible existing, otherwise Vendor-Specific)
  • Respecting defined HTTP verbs, status codes and headers
  • The unpronounceable HATEOAS principle (always reminds me of PCMCIA - People Can't Memorize Computer-Industries Acronyms), i.e. the use of links or "hyermedia controls" in resources to make the state transition possibilities (the ST in REST) navigable.
  • Support for HTTP caches.

Among other things, this has resulted in an open source project http://github.com/otto-de/jsonhome that allows an application to publish or also consume a json-home document.

1.D) Data and data supply

Since the application is an online store, chances are that many subsystems need to know something about products. But if they do not use a common database, how will information be shared? We have two options for this:

  • Creating redundancy via data supply processes.
  • Ad-hoc requests via REST interface

Data supply processes are always asynchronous in the background. No customer should have to wait for such processes. Inconsistencies between the systems are deliberately accepted.

The accesses between the systems are always done via PULL mechanisms such as AtomPub feeds, because this way the coupling between the systems can be reduced. Since we have to expect inconsistencies anyway, a few seconds delay compared to an update via PUSH is not important.

If such inconsistencies are unacceptable, systems may exceptionally make ad hoc requests to other verticals; however, we try to avoid this because it involves tight coupling between systems.

However, the core of the architecture principle is that only one vertical is leading for all data. All other systems only access the leading vertical via REST interfaces and keep redundant data if needed. The "truth" about a datum is in the hands of the leading system.

2. micro-architecture

In contrast to macro-architecture, micro-architecture is about the "architecture in miniature", i.e. that of the individual verticals.

mikroarchitektur-otto
mikroarchitektur-otto

Since sovereignty over the verticals is the responsibility of the relevant teams, there are no overarching guidelines here. It is not prescribed which frameworks must be used or what the structure of the application must look like. Just a few flanking agreements.

2.A) Buy when non-core

We do not see our core competence in, for example, developing our own database or our own front-end frameworks. Instead, we help ourselves to the market here and either buy things in or simply use a "product" from the open source environment. What exactly is defined as "core", on the other hand, is again up to the team to decide.

2.B) Common base technologies

Currently, all teams use MongoDB as their DBMS. In principle, a vertical could also opt for another persistence solution. However, this would entail operational overhead, so we want to avoid such changes.

There are a few less other things like Tomcat as a servlet container or even shared monitoring tools that are currently used similarly across teams, but are basically defined as part of the micro-architecture. So the teams could decide against such basics, but are encouraged to get into the ring beforehand and push their plan through in "big round".

In the beginning, we also developed a "common" library and used it across teams. In the meantime, however, we have come to the conclusion that the disadvantages of such a library (backward dependencies to 3rd party libraries are introduced again) outweigh the advantages.

What works much better:

"If there is code that teams want to share, develop it as an open source project, publish it on GitHub and treat it like a 3rd party dependency".

So far, three GitHub projects http://github.com/otto-de have been created this way:

  • hmac-auth: two libraries (client, server) for HMAC authentication + authorization when accessing REST resources.
  • jsonhome: libraries for publishing and consuming json-home documents.
  • wickettester: Unit testing for Wicket-based web applications.

Two more are in preparation:

  • mongo-migrations: tools for on-the-fly migration of MongoDB documents.
  • job-execution-framework: A framework for managing, executing and controlling asynchronously running jobs.
1 person likes it.

12Comments

  • […] Architekturprinzipien http://dev.otto.de/2013/04/14/architekturprinzipien-2/ […]

  • 27.03.2014 10:00 Clock

    Als ehermaliger Konzepter beim otto.de Produktmanagement hat mich Michael Wegener letztens auf diesen beitrag aufmerksam gemacht. Meine Frage: macht diese Art der Architektur vor allem bei sehr großen Websites Sinn, oder profitieren auch kleinere Webshops (sagen wir mal bis 50 Mio Umsatz) davon?

    Gruß
    Markus

  • Guido Steinacker
    27.03.2014 16:47 Clock

    Ob die Architektur angemessen ist, hängt von verschiedenen Parametern ab:
    1. Wie wahrscheinlich ist es, dass mehr als ein oder zwei Entwicklungsteams an der Software arbeiten werden?
    2. Wie groß ist die Chance, dass die Anwendung in sagen wir mal einem Jahr ein unhandlicher Monolith mit (je nach Programmiersprache) zigtausenden Zeilen Code ist?
    3. Dann gibt es natürlich noch die Frage nach den Anforderungen hinsichtlich horizontaler Skalierbarkeit des Systems: steht zu befürchten, dass zwei bis fünf Instanzen der Software in einem Load-Balancing Cluster nicht mehr ausreichen werden?
    4. Möchte ich vielleicht in der Lage sein, irgendwann einmal einzelne Subsysteme auszutauschen, ohne gleich die gesamte Anwendung umbauen zu müssen?
    5. Habe ich dezentrale Teams an verschiedenen Standorten, die sehr unabhängig voneinander arbeiten müssen?
    6. Ist es mir wichtig, dass Teams mit verschiedenen Programmiersprachen etc. arbeiten können?

    Gruß, Guido

  • 07.02.2014 13:12 Clock

    Guido, müsste es ganz oben in der Inhaltsübersicht nicht "Dezentrale Verantwortung für Daten und Datenversorungsprozesse" statt "zentrale ..." heißen?

  • Guido Steinacker
    07.02.2014 13:19 Clock

    Hi Alex,
    gemeint ist, dass es für jedes Datum (z.B. ein Produkt) genau ein führendes System gibt. Der Datenversorgungsprozess für Produkte ist also "zentral" einem Team bzw. System zugeordnet. Andere Datenversorgungen liegen in der Hoheit anderer Teams, das könnte man also auch als "Dezentrale Verantwortung" bezeichnen - es kommt halt darauf an, wie man es betrachtet.

    Viele Grüße, Guido

  • […] wir 2011 mit der Neuentwicklung unseres Online-Shops otto.de starteten, wählten wir frühzeitig eine verteilte, vertikal geschnittene Architektur. Erfahrungen mit unserem Altsystem zeigten uns, […]

  • […] Architekturprinzipien […]

  • […] the details of this architecture in an article in  OBJEKTspektrum (German), a different blog post (German) and at conferences […]

  • […] Deployment von Microservices verschwimmen die Grenzen zwischen Mikro- und Makroarchitektur. Während das Team die Mikroarchitektur für jeden Service individuell entscheiden kann, muss man […]

  • […] 德语的Otto TechBlog )以及 Galeria Kaufhof 。在 scs-architecture.org […]

  • 08.05.2017 17:18 Clock

    Hi, Vielen Dank für den interessanten Einblick. Ich habe eine Frage zur "Daten und Datenversorung".

    Wenn die Verantwortung bei jeder Vertikale selbst liegt, wie löst ihr das Problem das beim Skalieren keine unnötigen PULL's passieren. Sagen wir die Vertikale synchronisiert sich alle 60 Minuten. Aus sicht der Skalierung wird jeder Node gleich behandelt. Nach 60 Minuten würde ein PULL passieren. Bei 100 Nodes im worst case 100 mal. Welchen Lösungsweg seit ihr hier gegangen?

  • […] weiterhin möglich, da diese ähnliche Konzepte und Services bieten und wir bereits mit dem Lhotse Projekt große Vorarbeit geleistet haben, indem wir unseren Monolithen in hunderte kleine schnell zu […]

Write a comment
Answer to: Reply directly to the topic

Written by

Guido Steinacker

Similar Articles

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.