Projekt mikrousług dla wielu najemców

13

Jesteśmy w trakcie migracji aplikacji monolitycznej do architektury mikrousług. Ze względu na niektóre wymogi regulacyjne musimy przechowywać dane klienta z różnych krajów w osobnych (specyficznych dla danego kraju) bazach danych. Tj. Db dla klientów z USA, db dla klientów z Wielkiej Brytanii ...

Następujące projekty, które rozważamy, są następujące:

Opcja 1: Aplikacja dla wielu dzierżawców z obsługą hibernacji dla wielu dzierżawców, którą można skalować do N liczby razy w zależności od zapotrzebowania (pomyśl o kubernetach). Pojedyncze wystąpienie tej aplikacji będzie mogło połączyć się ze wszystkimi bazami danych.

Opcja 2: Wdróż 1 instancję mikrousług na bazę danych kraju. Z bramą API przed nimi, kierującą ruchem

Gdybyś miał zaprojektować tego typu system, jakie byłyby twoje wybory?

Witaj świecie
źródło
3
Myślę, że będzie to zależeć od twoich konkretnych wymagań funkcjonalnych i niefunkcjonalnych.
Robert Harvey
Różne bazy danych, ale ta sama instancja to czyta? Czy nie narusza to również wymogów regulacyjnych?
Jimmy T.
Opcja 1 nie wydaje się zbyt dopasowana do stylu architektury Microservices.
Laiv
Wspominasz o Kebernetes, ale nie jest jasne, czy używasz kontenerów, czy nie. Jeśli robisz to z Dockerem (na przykład), po prostu utworzysz aplikację, która łączy się z bazą danych. Następnie podczas uruchamiania kontenera i określania szczegółów połączenia za pomocą parametrów i / lub konfiguracji. Posiadanie jednej aplikacji, która łączy się z wieloma podobnymi bazami danych, stwarza tylko potencjalne problemy. Nie dodaje nic dobrego do projektu.
JimmyJames,

Odpowiedzi:

4

Myślę, że opcja 2 nie jest zła, ale może nie być potrzebna. Mikrousługi umożliwiają zaspokojenie potrzeb wielu aplikacji.

Dużym czynnikiem tutaj jest to, czy istnieje jakaś różnica między tymi dwoma schematami i czy kiedykolwiek będzie w przyszłości.

Zazwyczaj myślę, że używanie interfejsów do repozytoriów jest niepotrzebne; jednak w tym przypadku może być to warte wysiłku. Fabryki repozytoriów będą dla Ciebie ważne.

Mój problem z opcją 1 polega na tym, że jest ona zbyt specyficzna. Powinieneś być w stanie przejść od konfiguracji, którą opisałeś, do dwóch oddzielnych instancji, z których każda wskazuje na swoją własną bazę danych. Aplikacja NIE powinna troszczyć się o to, skąd pochodzi jej dane.

Chociaż schemat nie różni się dla dwóch różnych baz danych, możesz mieć jedno repozytorium z łatwością sobie z nimi radzić, bez różnicy między aplikacją:

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);

Jeśli schematy DB kiedykolwiek staną się rozbieżne między USA a Wielką Brytanią, wówczas podzielisz tę funkcjonalność na dwa całkowicie różne repozytoria. Byłoby to łatwe, ponieważ wszystko, co musisz zrobić, to zmienić fabrykę.

TheCatWhisperer
źródło
1
Nie rozumiem, dlaczego potrzebujesz tej fabryki. Dlaczego po prostu nie podać ścieżki do szczegółów konfiguracji podczas uruchamiania? Dzięki temu musisz modyfikować kod za każdym razem, gdy chcesz dodać nowy region / kraj.
JimmyJames,
1
Problem tutaj nie dotyczy użytkowników w różnych krajach ... dotyczy różnych baz danych. co jeśli istnieją różne schematy? Dlaczego klasa konsumująca powinna być odpowiedzialna za ustalenie, skąd wziąć ciąg połączenia DB?
TheCatWhisperer
Nie wiem o co ci chodzi. Nic w kodzie nie powinno być odpowiedzialne za „ustalenie”, skąd wziąć ciąg połączenia. To konfiguracja. Nie rozumiem, dlaczego różni się to od używania konfiguracji baz danych QA w porównaniu do produkcji. Nie umieszczasz tego w kodzie, prawda?
JimmyJames,
Jest to jedna aplikacja komunikująca się z dwiema bazami danych.
TheCatWhisperer
Myślę, że źle zrozumiałeś problem: „musimy przechowywać dane klienta z różnych krajów w osobnych (specyficznych dla danego kraju) bazach danych”. Nie ma wymogu, aby jedna instancja „aplikacji” komunikowała się z dwiema bazami danych. Wątpię, że to tylko dwa DB. OP prawdopodobnie oznaczało „np.” Podczas pisania „tj.”
JimmyJames,
0

Wybrałbym drugą opcję, która daje mniejsze tarcie w rozwoju i wdrażaniu.

Umożliwi to lepszą skalowalność i dostępność oraz lepsze opcje wdrażania bez przestojów, ponieważ aplikacja została rozpowszechniona w 1 (lub co najmniej jednym) wystąpieniu na region w przeciwieństwie do co najmniej jednego dla całego świata.

Gdy zmieniają się wymagania, możesz mieć więcej logiki biznesowej specyficznej dla regionu, a być może również zmiany danych, spróbuję podzielić kod i jego dane na region, unikając dzielenia logiki biznesowej specyficznej dla regionu (możesz w końcu dzielić trochę podstawowego kodu).

Ma sens?

Sean Farmar
źródło