Conception de microservices à locataires multiples

13

Nous sommes en train de migrer une application monolithique vers une architecture de microservices. En raison de certaines exigences réglementaires, nous devons conserver les données des clients de différents pays dans des bases de données distinctes (spécifiques au pays). C'est à dire db US pour les clients US, UK db pour les clients UK ...

Les conceptions suivantes que nous envisageons sont les suivantes:

Option 1: une application multi-locataire avec une prise en charge multi-locataire en hibernation qui peut être adaptée à N nombre de fois en fonction de la demande (pensez aux pods kubernetes). Une seule instance de cette application pourra se connecter à toutes les bases de données.

Option 2: déployer 1 instance de microservice par base de données de pays. Avec une passerelle API devant eux acheminant le trafic

Si vous deviez concevoir ce type de système, quels seraient vos choix?

Bonjour le monde
la source
3
Je pense que cela dépendra de vos besoins fonctionnels et non fonctionnels spécifiques.
Robert Harvey
Différentes bases de données mais la même instance la lit-elle? Cela ne viole-t-il pas également l'exigence réglementaire?
Jimmy T.
L'option 1 ne semble pas trop alignée sur le style d'architecture des microservices.
Laiv
Vous mentionnez Kebernetes mais il n'est pas clair si vous utilisez des conteneurs ou non. Si vous faites cela avec Docker (par exemple), vous créez simplement une application qui se connecte à une base de données. Ensuite, lorsque vous démarrez le conteneur et spécifiez les détails de la connexion via les paramètres et / ou la configuration. Avoir une application qui se connecte à de nombreuses bases de données similaires ne crée que des problèmes potentiels. Cela n'ajoute rien de bon à la conception.
JimmyJames

Réponses:

4

Je pense que l'option 2 n'est pas mauvaise, mais peut-être pas nécessaire. Les micro-services vous permettent de répondre aux besoins de plusieurs applications.

Un grand facteur ici est de savoir s'il y a une différence entre les deux schémas et s'il y en aura un à l'avenir.

Habituellement, je pense que l'utilisation d'interfaces pour les référentiels n'est pas nécessaire; cependant, cela pourrait valoir la peine dans ce cas. Les usines de dépôt seront importantes pour vous.

Mon problème avec l'option 1 est qu'elle est trop spécifique. Vous devriez pouvoir passer de la configuration que vous avez décrite à deux instances distinctes pointant chacune vers sa propre base de données facilement. L'application ne doit PAS S'INSCRIRE OERE ELLE OBTIENT SES DONNÉES.

Bien que le schéma ne diffère pas pour vos deux bases de données différentes, vous pouvez avoir un référentiel facilement gérer les deux, sans que l'application ne sache la différence:

public class MyEntityRepository : ISavesMyEntity, IGetsMyEntity
{
    public MyEntityRepository(string connectionString)
    {
       _connectionString = connectionString;
    }
}

public class MyEntitySaverFactory
{
    public ISavesMyEntity GetSaver(User user)
    {
        if (user.IsUK)
            return new MyEntityRepository(Config.Get("UKConnString"));
        if (user.IsUS)
            return new MyEntityRepository(Config.Get("USConnString"));
        throw new NotImplementedException();
    }
}

//USE
ISavesMyEntity saver = factory.GetSaver(currentUser);
saver.Save(myEntityInstance);

Si les schémas de base de données deviennent jamais disparates entre les États-Unis et le Royaume-Uni, vous diviserez alors la fonctionnalité en deux référentiels complètement différents. Ce serait facile, car il vous suffirait de changer d’usine.

TheCatWhisperer
la source
1
Je ne comprends pas pourquoi vous avez besoin de cette usine. Pourquoi ne pas simplement passer le chemin des détails de configuration au démarrage? Avec cela, vous devez modifier le code chaque fois que vous souhaitez ajouter une nouvelle région / pays.
JimmyJames
1
Le problème ici n'est pas de traiter avec des utilisateurs dans des pays différents ... il s'agit de différentes bases de données. Et s'il y a des schémas différents? Pourquoi la classe consommatrice devrait-elle être chargée de déterminer où obtenir la chaîne de connexion DB?
TheCatWhisperer
Je ne sais pas ce que tu veux dire. Rien dans le code ne devrait être responsable de «déterminer» où trouver la chaîne de connexion. C'est la configuration. Je ne vois pas pourquoi cela est différent de l'utilisation de la configuration des bases de données QA par rapport à la production. Vous ne mettez pas si des instructions dans le code pour cela, n'est-ce pas?
JimmyJames
Il s'agit d'une application parlant à deux bases de données.
TheCatWhisperer
Je pense que vous comprenez mal le problème: "nous devons conserver les données des clients de différents pays dans des bases de données distinctes (spécifiques au pays)" Il n'est pas nécessaire qu'une seule "instance" d'application parle à deux bases de données. Je doute que ce ne soit que deux DB. L'OP signifiait probablement «par exemple» quand ils ont tapé «ie»
JimmyJames
0

J'irais avec la deuxième option, elle donne moins de friction dans le développement et le déploiement.

Cela permettra une meilleure évolutivité et disponibilité et de meilleures options de déploiement sans interruption de service, car vous avez distribué votre application à 1 (ou au moins une) instance par région, par opposition à au moins une pour le monde entier.

Comme les exigences changent, vous pourriez avoir une logique métier plus spécifique à la région et éventuellement des modifications de données, j'essayerais de diviser le code et ses données par région, et d'éviter de partager la logique métier spécifique à la région (vous pourriez finir par partager du code principal).

Ça a du sens?

Sean Farmar
la source