Eine Anwendung Mehrere Instanzen und verschiedene DB

7

Ich erstelle eine Case-Management-Anwendung und eine der Anforderungen ist, dass jeder Client seine eigene Datenbank mit einer eigenen URL bekommt. Es ist jedoch ein Alptraum, mehrere Instanzen der Anwendung beim Upgrade zu verwalten. Ich verwende IIS 7 ASP.NET MVC. Ich möchte eine Anwendung haben und die Anwendung wissen lassen, von welcher Datenbank die Daten abhängig von der Benutzerauthentifizierung abgerufen werden. Gibt es eine praktikable Alternative?

    
Mike Diaz 30.12.2013, 14:00
quelle

7 Antworten

11

Ja, es ist besser, wenn möglich eine Instanz der Anwendung zu haben, sonst wird es kompliziert. Wenn die Funktionen für verschiedene Clients unterschiedlich sind, verwenden Sie Feature-Flags, um Funktionen für jeden Client / Benutzer ein- und auszuschalten. Siehe unten Artikel von Martin Fowler darüber. Feature-Flags können pro Benutzer oder Client sein. Facebook und einige andere große Websites verwenden Feature-Flags effektiv.

Ссылка

In Bezug auf die Datenbank denke ich, dass Sie eine Gemeinsame Datenbank haben können, die alle grundlegenden Informationen einschließlich aller Clients enthält und dann andere spezifische Datenbanken für jeden Client hat, die alle anderen hat Daten für den Kunden.

Wenn ein Benutzer eine clientspezifische URL in der Session_Start -Methode von Global.asax antrifft, wird Logik hinzugefügt, um die entsprechende Verbindungszeichenfolge abzurufen und in Sitzung zu speichern ( Session["ClientDbConnectionString"] ), damit Sie sie immer dann verwenden können, wenn Sie Daten aus der Client-DB benötigen.

Ich würde vorschlagen, dass Sie alle Verbindungszeichenfolgen in einer Tabelle in Common-Datenbank speichern (mit einem Schlüssel, der jeden Client identifiziert), damit Sie eine neue Verbindungszeichenfolgendatei hinzufügen können, wenn Sie einen neuen Client an Bord haben möchten. Immer wenn Sie eine neue Version erstellen, würde ich vorschlagen, alle Client-Datenbanken zusammen zu aktualisieren, anstatt nur eine Client-DB zu aktualisieren, sonst wird sie nach einer Weile nicht mehr zu verwalten sein.

    
Adarsh Shah 04.01.2014, 20:34
quelle
9

Ihre Frage ist wirklich nur eine Frage des Eisbergs. Mandantenfähigkeit ist ein komplexes Thema. Eine Verbindung pro Client mit der Tenant-Datenbank ist nur ein Aspekt. Es gibt noch andere Aspekte zu beachten:

  • Ausbalancierung von Mandanten: Wie stellen Sie sicher, dass Mandanten, die viel schneller wachsen als der Durchschnitt, angemessene Ressourcen erhalten und andere Mandanten nicht überlagern, die auf demselben Speicher (z. B. dieselbe Instanz) zusammengeschlossen sind. Wie bewegt man einen Mieter, der gewachsen ist? Wie aggregieren Sie kleine Mieter mit geringer Aktivität?
  • Isolation von Ressourcen: Ein Mandant kann einen großen Prozentsatz der Ressourcen verbrauchen (z. B. kann er eine Abfrage in der Datenbank ausführen, die die gesamte CPU aufnimmt und alle anderen Abfragen verhungern lässt), wie gewährleisten Sie anderen Mandanten die Fairness sind zusammengelegt?
  • geteilte Daten. Änderungen an gemeinsam genutzten Daten replizieren (Daten, die allen Mandanten gemeinsam sind, zB Nachschlagetabellen) kann problematisch sein.
  • Schemaänderungen. Dies ist eines der kniffligsten Themen. Datenbankschema und -code werden normalerweise synchron geändert (Code erwartet ein bestimmtes Schema), und die Bereitstellung einer Schemaänderung für alle Mandanten kann problematisch sein.

Ich empfehle Ihnen, das Multi-Tenant Data Architecture Whitepaper zu lesen. Dies stellt drei grundlegende Ansätze vor:

Zusätzlich würde ich die Option SQL Azure Federations hinzufügen (was nicht der Fall war) verfügbar zu der Zeit, als das Weißbuch geschrieben wurde). Der Artikel diskutiert die Vor- und Nachteile dieser Ansätze aus Sicht der Datenbank / Speicher, unter Berücksichtigung von Dingen wie:

  • Speicherkosten
  • Sicherheit
  • Verfügbarkeit
  • Skalierbarkeit
  • Leichtigkeit der Schemaänderung (App-Upgrade)
  • Erweiterbarkeit

Auf der Client-Seite ist mir keine MVC-Erweiterung bekannt, die für den Multi-Tenant-Fall hilfreich ist, etwas in der Art des act_as_tenant Juwel in Rails.

  

fängt an, ein Alptraum zu sein, um mehrere Instanzen der Anwendung beim Upgraden aufrechtzuerhalten.

Dies ist tatsächlich eines der größten Probleme in Multi-Tenant-Architekturen. Selbst wenn Sie die Reibung beseitigt haben, das Upgrade in einer DB tatsächlich durchzuführen, ist es immer noch ein schwer zu lösendes Problem. Sofern Sie sich keine Downtime für alle Mandanten leisten und das gesamte System offline schalten, alle Tenant-Datenbanken aktualisieren, neuen Code implementieren, der ein neues Schema versteht, und dann alle Mandanten online schalten, ist dies aufgrund des App-Codes eine Herausforderung (der ASP / MVC-Code) muss in der Lage sein, beide Versionen (alt und neu) gleichzeitig zu verstehen. Es ist nicht unmöglich zu lösen, aber es ist schwierig und muss sorgfältig codiert werden.

Dies ist ein wichtiger Teil, wenn "die Reibung des tatsächlichen Upgrades beseitigt wird". Ich mache keine Prozedur, die Sie zum Bereitstellen eines Upgrades verwenden. Es ist wichtig, dass das Upgrade automatisch und ohne manuellen Eingriff durchgeführt wird. Diff-basierte Tools werden manchmal verwendet, wie SQL Compare von Red-Gate oder sogar Visual Studio vsdbcmd.exe . Mein bevorzugter Ansatz ist jedoch die Verwendung von Upgrade-Skripts und Metadaten-Versionierung in der Anwendung. Weitere Informationen finden Sie unter Versionskontrolle und Ihre Datenbank . Als Referenz dient dieser Ansatz im Wesentlichen dem Rails Migrations -Ansatz.

    
Remus Rusanu 06.01.2014 10:01
quelle
2

Sie müssen die Verbindungszeichenfolge für jeden Benutzer irgendwo speichern (vielleicht in der Benutzertabelle?) und diesen Wert nachsehen, wenn Sie eine neue db-Verbindung erstellen. Das bedeutet, dass Sie keine Verbindungszeichenfolge aus web.config verwenden können, aber ich nehme an, Sie wissen, wie Sie eine neue db-Verbindung mit einer benutzerdefinierten Verbindungszeichenfolge erstellen können.

    
Zaphod 30.12.2013 14:07
quelle
2

Wenn ich Sie gut verstehe, müssen Sie Authentifizierung für jeden Kunden. Wenn der Client erfolgreich autorisiert wurde, sollte er auf seine Site umgeleitet werden, was bedeutet, dass die Verbindungszeichenfolge lauten sollte programmatisch geändert werden .

Alternativ können Sie die Anzahl der Verbindungszeichenfolgen in der Datei web.config definieren. Dann können Sie es verwenden, hängt von der Client-Autorisierung ab: Gewusst wie: Lesen von Verbindungszeichenfolgen aus der Datei "Web.config"

Hier ist ein Beispiel für die Einstellung von web.config:

%Vor%

Prost!

    
Maciej Los 05.01.2014 19:58
quelle
2

Ein Problem sehe ich darin, dass Sie jetzt die Anwendung und ihre Datenbank trennen.

In einer gewöhnlichen Situation werden sie zusammen aktualisiert. Sie könnten jetzt mit einer aktualisierten Anwendung und einer oder mehreren Datenbanken, die nicht aktualisiert werden, enden.

Ich denke, Adarsh ​​Shahs Antwort ist sehr gut, aber es vermisst diesen Punkt.

Meine Frage wäre: Warum können Sie diese Datenbanken nicht zusammenführen?

Dafür gibt es Lösungen. Zum Beispiel:

Angenommen, Sie haben einen Tabellennamen Cases. Erstellen Sie eine Ansicht, z. B. Cases_V (V aus Sicht). Legen Sie bei der Anmeldung eine Sitzungsvariable CompanyId fest (ich denke, das ist in SQL Server möglich, zumindest in Oracle, die ich verwende).

Filtern Sie in der Ansicht die Tabelle für diese Sitzungsvariable.

Die SQL von Cases_V würde so aussehen (in Oracle-Syntax):

%Vor%

In Ihrer Anwendung würden Sie diese Ansicht folgendermaßen verwenden:

%Vor%

Dies verhindert, dass Benutzer auf Informationen von anderen "Installationen" zugreifen und die Wartung minimieren.

    
Patrick Hofman 06.01.2014 09:37
quelle
1

AdarshShah-Anweisung ist sehr korrekt. Sie sollten die Verbindungszeichenfolgen verschiedener Datenbanken in einer separaten MetaDatabase verwalten, um die Identifizierung der jeweiligen Verbindungszeichenfolge des bestimmten Clients zu vereinfachen, insbesondere in einer Multi-Tenant-Umgebung Möglicherweise müssen Sie eine dedizierte Datenbank oder ein bestimmtes Schema für einen Client ausrollen / zuweisen. Es kann daher ein Alptraum werden, Verbindungszeichenfolgen in der XML-Datei wie SQL.Config oder Web.Config zu verwalten und zu verwalten.

Ich bin Teil einer Organisation, in der wir uns auf den Aufbau von Multi-Tenant-Framework spezialisiert haben, das von ISVs und Entwicklern verwendet werden kann, um SaaS-Anwendungen schneller zu entwickeln, ohne dabei die üblichen nicht-funktionalen Anforderungen zu analysieren und zu verstehen. Eine der primären Komponenten des Frameworks ist der Data Shader, der genau das Gleiche tut.

Bitte sehen Sie Ссылка

    
Ilyas F 06.01.2014 04:42
quelle
1

Ich werde vorstellen, wie ich versuchen würde, dieses Problem zu lösen.

Zuallererst müssen mehrere Verbindungszeichenfolgen in Ihrer Anwendungskonfiguration vorhanden sein. Ich empfehle Ihnen, Entity Framework für DB Management zu verwenden, wenn Ihre App in ASP.NET MVC ist. Sie können Wrapper über die DbContext- und ObjectContext-Klassen erstellen (ich meine Sie Wrapper, um die erwähnten Klassen zu erben) und Factory-Methode verwenden, um den Kontext basierend auf dem angemeldeten Benutzer auszuwählen.

Ich nehme an, dass Sie die Datenbank kennen, in der die Benutzer gespeichert sind. Aus Global.asax gehen Sie zuerst zu diesem dbContext und wählen dann basierend auf dem Benutzerprofil den richtigen Kontext.

    
arnoldrob 11.01.2014 14:36
quelle