Kolumne

EnterpriseTales: Von der klassischen Webanwendung zur Multi-Channel-Architektur

Lars Röwekamp

Klassische Webanwendungen scheinen ausgedient zu haben. Multi-Channel ist das neue Schlagwort. Immer mehr Unternehmen setzen auf den Mobile-Kanal, mit dem Ziel, neue Kundengruppen zu gewinnen. Aber geht das so einfach? Spielt unser gutes, altes Enterprise-Backend da überhaupt mit?

Mobile Devices gewinnen in den letzten Jahren auch im Umfeld von B2C immer stärker an Bedeutung. Da ist es wenig überraschend, dass Unternehmen Tablets und Smartphones als zusätzliche lukrative Kanäle identifiziert haben, über die sie ihren Kunden einen Mehrwert bieten könnten.

Um aber aus technologischer Sicht, neben dem klassischen Webclient, auch den neuen Kanälen gerecht zu werden, bedarf es nicht selten eines Refactorings des eigenen Backends. Nur in den wenigsten Fällen sind die bestehenden, meist historisch gewachsenen Architekturen so aufgestellt, dass sie den zusätzlichen Anforderungen genügen.? Gibt es überhaupt zusätzliche Anforderungen? Sind Tablets und Smartphones nicht einfach die kleinen Brüder des Webs? Schließlich gibt es mit Responsive Design doch bereits eine Lösung für das Problem, oder?

Gehen wir noch einmal einen Schritt zurück und fragen uns, was genau wir eigentlich unter Multi-Channel verstehen. Basis ist das Grundkonzept, Kunden über verschiedene Kanäle zu bedienen. Neben Web, Tablet und Smartphone zählt auch das klassische physikalische Ladengeschäft als eigener Channel dazu. Denken wir exemplarisch an einen Onlineshop, dann sollte der Kunde sowohl über das Web als auch über Smartphone oder Tablet Produkte (aus)suchen, in den Warenkorb legen und kaufen können. Natürlich kann dies nicht auf allen Endgeräten mit demselben UI geschehen. Aber zum Glück gibt es ja Responsive Design und passende Webframeworks wie Bootstrap, die unseren HTML5-basierten Onlineshop auf allen Devices gleich gut aussehen lassen.

Mulit-, Cross-, Omni-Channel

Das Problem an dem eben beschriebenen Lösungsansatz ist, dass wir bei Multi-Channel davon ausgehen, dass ein und derselbe Use Case auf allen Devices zum Ziel führt – einem glücklichen Kunden. Weiterhin gehen wir davon aus, dass, einmal mit einem Kanal gestartet, der Kunde bei diesem Kanal bleibt. Hier darf die ketzerische Frage erlaubt sein, wie ein Unternehmen sein Geschäftsmodell ausweiten möchte, wenn es nach wie vor nur dieselbe Leistung anbietet – nur über unterschiedliche Kanäle. Erfahrungen zeigen, dass in dem heutigen Wettbewerbsumfeld eine reine Multi-Channel-Strategie im günstigsten Fall zu einer Verlagerung des eigenen Geschäfts führt. Kunden, die bisher ausschließlich im Web gekauft haben, kaufen nun auch via Tablet oder Smartphone. Aber kaufen sie dadurch mehr als vorher? Sicherlich nicht. Nicht selten kommt es sogar zu einem negativen Effekt. Genau dann, wenn die zusätzlichen Kanäle nicht die gewohnte Qualität bieten und der Kunde so das Vertrauen in die Innovationsfähigkeit des Unternehmens verliert.

Responsive Design ist sicherlich eine gute und richtige Lösung für Multi-Channel-Marketing und Sales, aber reicht das aus? Ziel sollte es doch sein, jeden Channel so zu nutzen, dass er aus Sicht des Konsumenten genau richtig gewählt wurde. Anders formuliert gilt es für jeden Channel, die richtigen Use Cases zu finden. Nämlich genau die, die den größtmöglichen Mehrwert bringen. Nehmen wir als Beispiel eine Reise-App. Die Planung der Reise sowie die eigentliche Buchung nimmt man sicherlich per Laptop oder Tablet auf dem Sofa vor. Ist die Reise aber angetreten, möchte man Last-Minute-Aktionen wie spontane Upgrades eher auf dem Smartphone durchführen. Und auch aktuelle Informationen zur Reise – Verspätungsalarme oder Gate-Änderungen – machen auf dem Smartphone mehr Sinn als auf dem heimischen PC. Jeder Kanal hat also seine ganz eigenen Use Cases, welche die Vorzüge des jeweiligen Kanals sowie den Kontext, in dem dieser Kanal genutzt wird, bestmöglich nutzen. Spätestens hier verlassen wir das Feld von Multi-Channel und betreten die Wunderwelt von Cross-Channel und Omni-Channel.

W-JAX
Mike Wiesner

Data- und Event-driven Microservices mit Apache Kafka

mit Mike Wiesner (MHP – A Porsche Company)

Niko Köbler

Digitization Solutions – a new Breed of Software

with Uwe Friedrichsen (codecentric AG)

Software Architecture Summit 2017
Dr. Carola Lilienthal

The Core of Domain-Driven Design

mit Dr. Carola Lilienthal (Workplace Solutions)

Sascha Möllering

Reaktive Architekturen mit Microservices

mit Sascha Möllering (Amazon Web Services Germany)

Ressourcen vs. Views

Das größte Problem klassischer Webarchitekturen im Zusammenspiel mit Cross- oder Omni-Channel ist die Tatsache, dass das Backend speziell für den jeweiligen Kanal aufbereitete und optimierte Views liefert. Im Umkehrschluss bedeutet dies, dass das Backend sämtliche Use Cases für alle bekannten und am besten auch zukünftigen Kanäle kennen muss und darüber hinaus in der Lage ist, für den Kanal optimierte Views zu liefern. Viel sinnvoller ist dagegen, wenn das Backend dem Client lediglich Ressourcen – zum Beispiel über RESTful Calls – zur Verfügung stellt. Der Client kann so sein eigenes Domänenmodell verwalten und ist in der Lage, eigene UI-Controller zur Umsetzung der benötigten Use Cases zu realisieren. Die UI-Controller-Schicht wird bei diesem Ansatz also aus dem Backend herausgezogen und auf die verschiedenen Clients verlagert.

Ein weiteres nicht zu unterschätzendes Problem bei der Unterstützung zusätzlicher mobiler Kanäle ist das sich stark unterscheidende Nutzungsverhalten im Vergleich zum Webclient. Während man sich normalerweise an seinen PC oder Laptop setzt und sich dort für eine gewisse Zeit mit einer Anwendung beschäftigt, sieht das Verhalten auf einem Mobile-Client eher so aus, dass man das Gerät kurz herausholt, eine Information abfragt oder eine Aktion durchführt und dann die App wieder schließt. Dies führt zu sehr vielen kurzen Sessions auf Seiten des Backends und zu sehr vielen Requests. Es gibt genug Beispiele aus der Praxis, bei denen die Unterstützung des Kanals Smartphone plötzlich zu einem so großen Request-Aufkommen geführt hat, dass etablierte Serverstrukturen in die Knie gezwungen wurden.

Das eigentliche Problem liegt darin begründet, dass ein Nutzer einer mobilen Anwendung gewohnt ist, immer wieder nach dem aktuellen Status einer Information zu fragen. Ein gutes Beispiel ist der aktuelle Kontostand. Besonders zum Monatsende schaut man immer wieder in der Bank-App, ob das Gehalt schon überwiesen ist. Dies löst unzählige Requests aus, von denen die meisten zugehörigen Responses lediglich signalisieren, dass es keine neuen Daten gibt. Die Lösung für das Problem ist denkbar einfach. Anstatt wieder und wieder nach dem aktuellen Stand zu fragen – via HTTP Request – und so unnötige Serverlast zu erzeugen, merkt man sich auf dem Client den aktuellen Status und bittet den Server, sich proaktiv bei Änderungen zu melden. Im Webumfeld lässt sich dies via WebSocket realisieren. Bei einer nativen App dagegen würde man auf Notifications zurückgreifen. Handelt es sich um eine kleine Informationsmenge, so kann diese direkt als Bestandteil der serverseitigen Benachrichtigung mitgeschickt werden. Alternativ dient das Event oder die Notification als Trigger für den Client, dass sich genau jetzt ein Request lohnt, da neue Daten auf dem Server vorliegen.

Bounded Contexts vs. Applications

Einer weiteren Herausforderung, der wir uns im Backend stellen müssen, sind die Featurewünsche der verschiedenen neuen Kanäle. Selbst wenn wir es geschafft haben, einen Teil der Use-Case-Umsetzung auf die Clients zu verlagern, bleiben auf Seiten des Backends noch mehr als genug Change Requests abzuarbeiten. Mit dem bisherigen Ansatz, das Backend als großes Ganzes zu sehen, kommen wir da leider nicht weit. Änderungen müssen von allen Beteiligten abgesegnet werden, da sie unerwünschte Nebeneffekte auslösen könnten. Und selbst, wenn sie genehmigt wurden, sind die Releasezyklen des monolithischen Backends mit all seinen Testphasen deutlich zu lang, um den Anforderungen des Markts gerecht werden zu können. Was also tun?

Auch hier ist die Lösung des Problems wieder denkbar einfach – zumindest in der Theorie. Um auf geänderte Anforderungen schneller und gezielter reagieren zu können, gilt es, den monolitischen Servicelayer aufzulösen und in mehr oder minder unabhängige Scheiben, aka Bounded Contexts, zu zerschneiden; mehr oder minder unabhängig daher, da es natürlich auch weiterhin Abhängigkeiten geben wird. Diese werden aber im Gegensatz zu vorher durch wohldefinierte Schnittstellen abgebildet. Solange sich also an der Schnittstelle nichts ändert, können die einzelnen Bounded Contexts unabhängig deployt und releast werden. Und selbst wenn es Änderungen an den Schnittstellen gibt, ist von Anfang an klar, wen diese Änderungen betreffen werden. Entsprechend vereinfacht werden die Test- und Deployment-Szenarien.

Server vs. PaaS

Wir haben unsere Architektur bis dato dahingehend optimiert, dass wir Ressourcen statt Views ausliefern, und so einen Teil der Use-Case-Implementierung auf die verschiedenen Clients verlagert. Um unnötige Serverlast durch zu viele leere Requests zu vermeiden, setzen wir wann immer es Sinn macht auf WebSockets, Server-side Events oder Push Notifications. Unsere Businessservices finden sich nach wie vor auf dem Server. Um auch hier schneller auf Change Requests reagieren zu können, haben wir den monolithischen Servicelayer in kleinere Pakete geschnitten. Als Gradmesser dienen uns dazu Bounded Contexts, also in sich geschlossene fachliche Bereiche. Gibt es noch weiter Möglichkeiten der Optimierung, um sich der Herausforderung Cross-Channel zu stellen?

Neue Kanäle bedeuten, dass auch neue Herausforderungen an die Skalierung eines Systems gestellt werden. Bei herkömmlichen Provisionierungen, z. B. in dem hauseigenen Rechenzentrum, sind die Reaktionszeiten für dieses Geschäftsmodell meist nicht akzeptabel. Um auf Nummer sicher zu gehen, wird daher oft mit viel zu großen Systemen – und Kosten – gestartet, um so von Anfang an für den Best Case gerüstet zu sein. Kosten und Nutzen stehen dabei in keiner Relation. Spontanes Mitwachsen dagegen ist nur möglich, wenn man bei Bedarf schnell auf weitere Ressourcen, wie Rechner oder Speicher zurückgreifen kann. Hier kommen die verschiedenen Platform-as-a-Service-Anbieter ins Spiel. Damit lassen sich schnell und effizient zusätzlich benötigte Ressourcen provisionieren.

Fazit

Wow, kann es sein, dass wir ganz aus Versehen unsere klassische Mehrschichtarchitektur mal eben so in Richtung Microservices und Platform as a Service migriert haben? Das ging irgendwie zu einfach. Da muss es doch noch den einen oder andern Pferdefuß geben, oder? So einfach die beschriebenen Schritte auch klingen mögen, am Ende haben wir, ausgehend von einem Monolithen, ein stark verteiltes System geschaffen – mit all den Problemen, die ein solches System mit sich bringt. Wie gehe ich mit dem Thema Versionierung der Schnittstellen um? Und wie kann ich die Schnittstellen überhaupt testen? Was passiert, wenn ein Service mal nicht antwortet? Wer übernimmt im Fall von Fehlern die notwendige Compensation und das Error Handling? Wie halte ich die Domänenmodelle von Client- und Server synchron? Insbesondere, wenn es nicht nur einen Client gibt und sie nicht nur lesenden, sondern auch schreibenden Zugriff auf das Modell haben? Und wie sieht es mit dem Thema Security aus? Bisher habe ich meine Webanwendung eventuell nur hausintern genutzt und mir darum kaum Gedanken gemacht. All diese Fragen und viele weitere gilt es zu überdenken. In diesem Sinne: Stay tuned …

Geschrieben von
Lars Röwekamp
Lars Röwekamp
Lars Röwekamp ist Gründer des IT-Beratungs- und Entwicklungsunternehmens open knowledge GmbH, beschäftigt sich im Rahmen seiner Tätigkeit als „CIO New Technologies“ mit der eingehenden Analyse und Bewertung neuer Software- und Technologietrends. Ein besonderer Schwerpunkt seiner Arbeit liegt derzeit in den Bereichen Enterprise und Mobile Computing, wobei neben Design- und Architekturfragen insbesondere die Real-Life-Aspekte im Fokus seiner Betrachtung stehen. Lars Röwekamp, Autor mehrerer Fachartikel und -bücher, beschäftigt sich seit der Geburtsstunde von Java mit dieser Programmiersprache, wobei er einen Großteil seiner praktischen Erfahrungen im Rahmen großer internationaler Projekte sammeln konnte.
Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.