Mandantenfähige Webapps mit Laravel
Multitenancy ist eine Architektur, bei der eine einzige Instanz einer Softwareanwendung mehrere Kunden bedient.
In einer sogenannten "mandantenfähigen Umgebung" verwenden alle Kunden denselben Quellcode, jedoch hat jeder Kunde nur Zugriff auf seine eigenen Daten. Insbesondere SaaS-Produkte basieren oft auf einer mandantenfähigen Architektur.
Der Hauptvorteil einer mandantenfähigen Architektur liegt darin, dass sie die Wartungskosten senken kann. Alle Benutzer des Systems verwenden dieselbe Instanz, wodurch die Entwicklungs- und Wartungskosten stabil bleiben und Updates sowie Upgrades nur einmal durchgeführt werden müssen.
Was ist Mandantenfähigkeit?
In der Softwaretechnik ist Multitenancy ein Prinzip in der Softwarearchitektur, bei dem eine einzelne Instanz der Software auf einem Server läuft und mehrere Mandanten (Tenants) bedient. Ein Tenant ist eine Gruppe von Nutzern, die den gleichen Zugriff mit bestimmten Privilegien auf die Softwareinstanz haben.
Bei Multi-Tenancy ist eine Softwareanwendung so konzipiert, dass jeder Tenant über einen eigenen Bereich mit Anwendungsdaten, der Konfiguration, der Benutzerverwaltung und der mandantenspezifischen Anpassungen verfügt. Der Begriff wird auch in der Netzwerkarchitektur verwendet, wo ein einziger Server mehrere unabhängige Tenants oder Organisationen hostet.
Wozu dient mandantenfähige Software?
Mandantenfähige Software ermöglicht es, dass eine einzige Software-Instanz von mehreren Kunden genutzt werden kann, wobei die Daten und Einstellungen jeder Kundengruppe getrennt bleiben.
Das bedeutet, dass verschiedene Kunden die gleiche Software verwenden können, ohne dass ihre Informationen miteinander vermischt werden.
Welche Multi-Tenant-Architektur ist geeignet?
Welche Art von mandantenfähiger Architektur für dein Unternehmen geeignet ist, hängt von einer Reihe von Faktoren ab, darunter die Sensibilität der Daten, rechtliche Anforderungen ans Projekt, die Anzahl der Mandanten und die Organisationsstruktur.
Es gibt zwei Haupttypen von mandantenfähigen Architekturen: gemeinsame Datenbank oder getrennte Datenbanken pro Kunde. Eine weitere Umsetzungsmöglichkeit ist die Nutzung des gleichen Schemas mit geprefixten Tabellen innerhalb einer Datenbankinstanz. Wordpress nutzt diesen Ansatz wenn man eine Multisite-Installation verwendet.
Multitenancy mit einer gemeinsamen Datenbank
In einer Architektur mit gemeinsamer Datenbank teilen sich alle Mandanten dieselbe Datenbankinstanz. Das bedeutet, dass die Daten von mehreren bzw. allen Tenants (Mandanten) in der gleichen Datenbank gespeichert werden.
Die Trennung der Daten auf die Tenants wird i.d.R. durch eine group_id
oder organisation_id
ermöglicht und findet damit auf Codeebene statt.
Diese Form der Implementierung bietet keine physische Trennung der Daten. Eine gemeinsame Datenbank kann immer dann verwendet werden, wenn es keine rechtlichen Anforderungen an umfangreichere Datentrennung gibt.
Bei Multitenant-Implementierungen die mit einer gemeinsamen Datenbank arbeiten wird häufig die geringere Sicherheit als ein Nachteil angeführt weil Daten von mehreren Kunden in der gleichen Datenbank liegen.
Wir halten das für ein Scheinargument. Übliche und weit verbreitete Shopsysteme funktionieren beispielsweise nach dem gleichen Prizip: Kundendaten werden in einer zentralen Datenbank abgelegt. Weiterhin ist es eine Frage von sauberer und robuster Implementierung um sicherzustellen dass die Trennung der Mandanten sauber funktioniert. Die Daten auf verschiedene Datenbanken aufzuteilen sollte unserer Meinung nach keine Abkürzung sein um an der Softwarequalität oder der sauberen Implementierung zu sparen. Die Testabdeckung des Codes hier von besonderer Bedeutung.
Vorteile von Multitenancy mit einer Datenbank
Ein Mandantenfähiges Laravel System mit einer zentralen Datenbank erfreut sich grundsätzlich allen Vorteilen die Laravel bietet und sorgt damit für eine hoher Developer Experience und effizientes entwickeln.
Weitreichende Eingriffe ins Laravel Kernsystem bleiben aus und erleichern auch die Wartbarkeit eines Projekts bei zukünftigen Versionsupdates.
Ohne den Bedarf für jeden Mandanten eine eigene Datenbank anzulegen, lassen sich neue Mandanten schnell durch einen simplen Registrierungsprozess onboarden - quasi mit Boardmitteln von Laravel.
Multitenancy mit getrennten Datenbanken
Bei einer Architektur mit getrennten Datenbanken hat jeder Tenant seine eigene Datenbankinstanz. Das bedeutet, dass die Daten jedes Tenants von den anderen Tenants isoliert sind. Eine separate Datenbankarchitektur wird in der Regel verwendet, wenn es rechtliche Anforderungen zur Datentrennung gibt.
Achtung: Sackgasse!
Diese Art der Umsetzung ist deutlich aufwändiger und damit kostenintensiver. Wenn dieser Weg einmal eingeschlagen wird, kann er außerdem nur schwer bis gar nicht rückgägnig gemacht werden. Daher ist bereits zu Projektbeginn eine genaue Betrachtung unbedingt erforderlich. Ohne absolut notwendige Anforderungen ist eine Umsetzung mit mehreren Datenbanken nicht zu empfehlen.
Mehrere Datenbanken mit Laravel nutzen
Die Entwicklung von mandantenfähiger Software kann auf viele verschiedene Arten erreicht werden, die aufwändigere Methode ist die Verwendung mehrerer Datenbanken. Dieser Ansatz kann mit dem Laravel-Framework verwendet werden und ermöglicht es dir, für jeden Mandanten eine eigene Datenbank zu erstellen. Dadurch kann eine physische Isolierung der Daten erreicht werden. Diese Umsetzungsvariante ist ideal für Unternehmen, die eine umfassende Datentrennung benötigen.
Wenn pro Mandant eine Datenbank verwendet werden soll, empfehlen wir die Nutzung von Spaties Package "Multitenancy". Es erleichtert den Umgang mit separaten Datenbanken pro Mandant und liefert auch hilfreiche Artisan-Commands zu Verwaltung mit.
Zusätzliche Herausforderungen durch ein Multi-Database Setup
Wenn mehrere Datenbanken genutzt werden, wird es erforderlich stets zu wissen, mit welchem Tenant gerade gearbeitet werden soll. D.h. alle Requests, Artisan-Commands, Queues etc. müssen ihren Mandanten kennen (Tenant-Aware sein).
Onboarding neuer Kunden
Auch hier ist der Aufwand größer als gewöhnlich. Für jeden neuen Mandanten muss beim Onboarding (vgl. bei der Registrierung) eine neue Datenbank erstellt werden. Natürlich kann dieser Prozess automatisiert werden, es ist jedoch ein zusätzlicher und komplexer Infrastrukturanteil der mit Aufwänden verbunden ist, die eingespart werden können.
Wenn dieser Schritt nicht automatisiert wird, können neue Mandanten nur manuell oder Teilmanuell z.B. mit einem Artisan-Command hinzugefügt werden.
Wirkliche Vorteile von Mandantenfähiger Software
Die Vorteile der mandantenfähigen Softwareentwicklung liegen darin, dass sie Skaleneffekte voll ausschöpft, nahezu sofortige Elastizität bietet und die Softwarequalität durch eine höhere Testabdeckung verbessert. Eine einzige Instanz der Software kann mehrere Mandanten bedienen, was die Kosten im Vergleich zu herkömmlichen Entwicklungsmodellen senkt.
Umsetzung mit Laravel Boardmitteln
Weil eine Umsetzung mit mehreren Datenbanken nur sehr selten benötigt wird, beschränken wir uns hier auf die Umsetzung von Multitenancy mit einer einzeilnen Datenbank.
Grundsätzlich bringt Laravel bereits alles mit was gebraucht wird, um ein mandantenfähiges System zu entwickeln. Für eine ein-Datenbank-Lösung werden auch keine zusätzlichen Packages benötigt. Was es braucht, ist ein Model und eine Tabelle Organisations. In unseren Projekten bevorzugen wir die Bezeichnung "Organisation" für einen Mandanten, Tenant oder Group wäre aber genauso möglich.
Die jeweiligen Ressourcen die die App verwaltet, werden nun an diese Organisation gebunden. Dazu braucht es in den jeweiligen Tabellen nur eine Spalte "organisation_id". Via PhpUnit-Tests stellen wir lückenlos sicher dass kein Mandant die Daten des anderen sieht. Test Driven Development (TDD) ist in solchen Projekten ein unerlässlicher Ansatz. An den Kunden muss an dieser Stelle bereits frühzeitig kommuniziert werden warum diese Aufwände erforderlich und lohnenswert sind.
Laracon Talk zum Thema Multi Tenancy
Im Rahmen der Laracon 2017 wurde ein Vortrag zum Thema Multi-Tenancy von Tom Schlick gehalten.
Unsere Empfehlung
Multitenancy mit einer einzigen Datenbank ist eine gute Lösung, weil sie Skaleneffekte, nahezu sofortige Elastizität und eine verbesserte Softwarequalität ermöglicht. Außerdem bietet sie eine Trennung zwischen dem Eigentümer/Betreiber der Anwendung und den einzelnen Tenants, was die Sicherheit und Verwaltbarkeit erhöht.
Sofern es keine rechtlichen Anforderungen gibt, die eine tatsächliche, physische Datentrennung erforderlich machen, ist eine Mehrmandantenlösung mit einer Datenbank völlig ausreichend und zu empfehlen.
Weiteres Material:
- Vortrag von Tom Schlick zu Multitenancy in Laravel, Laracon 2017
- Wikipedia zu Mandantenfähiger Software
- Foto von Joshua Coleman