2011-09-25 3 views
6

J'ai été chargé de créer une application d'entreprise à plusieurs locataires. Il a une BLL Java/Glassfish utilisant des services web SOAP et un backend PostgreSQL. Chaque locataire a sa propre base de données, donc (dans mon cas au moins) "multi-locataire" signifie prendre en charge plusieurs bases de données par serveur d'application. Le serveur d'applications à locataire unique actuel initialise un pool de connexions C3P0 avec une chaîne de connexion obtenue à partir d'un fichier de configuration. Ma pensée est que maintenant il doit y avoir un pool de connexion par client/base de données desservi par le serveur d'applications.Mise en œuvre de l'hébergement multiclient pour une application d'entreprise mature

Une fois qu'un utilisateur est connecté, je peux le mapper au bon pool de connexions en recherchant son locataire. Mon principal problème est de savoir comment aller aussi loin - lorsqu'un utilisateur est connecté pour la première fois, la table User du serveur est interrogée et l'objet User correspondant est servi. Il semble que je devrais savoir quelle base de données utiliser avec seulement un nom d'utilisateur avec lequel travailler.

Ma seule idée décente est qu'il doit y avoir une base de données "config" - une base de données centralisée pour la gestion des informations sur les locataires telles que les chaînes de connexion. La BLL peut interroger cette base de données pour obtenir suffisamment d'informations pour initialiser les pools de connexions nécessaires. Mais comme je n'ai qu'un nom d'utilisateur avec lequel travailler, il me semble que j'aurais besoin d'une recherche de nom d'utilisateur centralisée, en d'autres termes une table UserName avec une clé étrangère à la table Tenant.

C'est là que mon plan de conception commence à sentir, me donnant des doutes. Maintenant, j'aurais des informations sur les utilisateurs dans deux bases de données distinctes, qui devraient être maintenues de façon synchrone (ajouts, mises à jour et suppressions d'utilisateurs). De plus, les noms d'utilisateur doivent maintenant être globalement uniques, alors qu'auparavant, ils devaient uniquement être uniques par locataire. Je suspecte fortement que je réinvente la roue, ou qu'il y ait au moins une meilleure architecture possible. Je n'ai jamais fait ce genre de chose auparavant, ni personne dans mon équipe, d'où notre ignorance. Malheureusement, l'application n'utilise que peu de technologies existantes (l'ORM a été lancé à la maison par exemple), notre chemin peut donc être difficile.

Je demande ce qui suit:

  • La critique de mon plan de conception existant et des suggestions pour améliorer ou retravailler l'architecture.
  • Recommandations des technologies existantes qui apportent une solution à ce problème. J'espère que quelque chose peut être facilement branché tard dans le jeu, bien que cela puisse être irréaliste. J'ai lu à propos de jspirit, mais j'ai trouvé peu d'informations à ce sujet - des commentaires sur ce sujet ou sur d'autres frameworks seront utiles.

MISE À JOUR: La solution a été mis en œuvre avec succès et déployé, et a passé le test initial. Merci à @mikera pour sa réponse utile et rassurante!

Répondre

5

Quelques réflexions rapides:

  • Vous aurez certainement besoin une certaine forme d'index de gestion des utilisateurs partagés (sinon vous ne pouvez pas associer une connexion client avec l'instance de base de données cible à droite). Cependant, je suggérerais de le rendre très léger, et de l'utiliser uniquement pour la connexion initiale. Votre objet Utilisateur peut toujours être extrait de la base de données spécifique au client une fois que vous avez déterminé la base de données.
  • Vous pouvez créer la clé primaire [ID client, nom d'utilisateur] afin que les noms d'utilisateur n'aient pas besoin d'être uniques entre les clients.
  • En dehors de cette couche d'index utilisateur léger, je voudrais garder la majorité des informations de l'utilisateur où il est dans les bases de données spécifiques au client. Refactoriser cela maintenant sera probablement trop perturbateur, vous devriez obtenir la capacité multi-locataire de base en premier lieu.
  • Vous devez conserver l'index partagé dans la synchronisation avec les bases de données client individuelles. Mais je ne pense pas que cela devrait être trop difficile. Vous pouvez également "tester" la synchronisation et corriger les erreurs avec un travail par lots, qui peut être exécuté du jour au lendemain ou par votre administrateur de base de données à la demande si quelque chose ne se synchronise jamais. Je traiterais les bases de données client en tant que maître et je l'utiliserais pour reconstruire l'index utilisateur partagé à la demande.
  • Au fil du temps, vous pouvez factoriser vers une couche de gestion des utilisateurs entièrement partagé (et même à la fin des bases de données de clients entièrement partagé si vous le souhaitez. Mais enregistrer ce pour une future itération .....
+0

+1 Cette réponse est rassurante: la base de données de config sera très légère - comme vous l'avez dit, utilisée uniquement lors de l'initialisation du pool de connexion et de la recherche du nom d'utilisateur. –