Diseño de microservicio multiempresa

13

Estamos en el proceso de migrar una aplicación monolítica a la arquitectura de microservicios. Debido a algunos requisitos reglamentarios, tenemos que mantener los datos del cliente de diferentes países en bases de datos separadas (específicas del país). Es decir, db de EE. UU. Para clientes de EE. UU., Db del Reino Unido para clientes de Reino Unido ...

Los siguientes diseños que estamos considerando son los siguientes:

Opción 1: una aplicación multiinquilino con soporte de hibernate multiinquilino que se puede escalar a N número de veces dependiendo de la demanda (piense en las vainas de kubernetes). Una sola instancia de esta aplicación podrá conectarse a todas las bases de datos.

Opción 2: Implementar 1 instancia de microservicio por base de datos de país. Con una puerta de enlace API frente a ellos enrutando el tráfico

Si diseñaras este tipo de sistema, ¿cuáles serían tus opciones?

Hola Mundo
fuente
3
Creo que dependerá de cuáles sean sus requisitos funcionales y no funcionales específicos.
Robert Harvey
¿Diferentes bases de datos pero la misma instancia lo está leyendo? ¿Eso no viola el requisito regulatorio también?
Jimmy T.
La opción 1 no parece demasiado alineada con el estilo de arquitectura de Microservicios.
Laiv
Menciona Kebernetes pero no está claro si está utilizando contenedores o no. Si está haciendo esto con Docker (por ejemplo), simplemente crearía una aplicación que se conecta a una base de datos. Luego, cuando inicie el contenedor y especifique los detalles de la conexión a través de parámetros y / o configuración. Tener una aplicación que se conecta a muchas bases de datos similares solo crea problemas potenciales. No agrega nada bueno al diseño.
JimmyJames

Respuestas:

4

Creo que la opción 2 no es mala, pero puede no ser necesaria. Los micro servicios son para permitirle lidiar con las necesidades de múltiples aplicaciones.

Un factor importante aquí es si hay alguna diferencia entre los dos esquemas, y si alguna vez habrá alguna en el futuro.

Por lo general, creo que usar interfaces para repositorios es innecesario; sin embargo, podría valer la pena el esfuerzo en este caso. Las fábricas de depósitos serán importantes para usted.

Mi problema con la opción 1 es que es demasiado específico. Debería poder pasar de la configuración que describió a dos instancias separadas, cada una apuntando a su propio DB fácilmente. La aplicación NO DEBE ATENTARSE DE DONDE RECIBE SUS DATOS.

Si bien el esquema no difiere para sus dos bases de datos diferentes, puede tener un repositorio que se ocupe fácilmente de ambas, sin que la aplicación sepa la diferencia:

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 los esquemas de DB se vuelven dispares entre los EE. UU. Y el Reino Unido, entonces dividiría la funcionalidad en dos repositorios completamente diferentes. Esto sería fácil, ya que todo lo que tendría que hacer es cambiar su fábrica.

TheCatWhisperer
fuente
1
No entiendo por qué necesitas esta fábrica. ¿Por qué no simplemente pasar la ruta a los detalles de configuración al inicio? Con esto, debe modificar el código cada vez que desee agregar una nueva región / país.
JimmyJames
1
El problema aquí no es tratar con usuarios en países separados ... se trata de diferentes bases de datos. ¿Qué pasa si hay diferentes esquemas? ¿Por qué la clase consumidora debe ser responsable de averiguar dónde obtener la cadena de conexión DB?
TheCatWhisperer
No se a que te refieres. Nada en el código debe ser responsable de "averiguar" dónde obtener la cadena de conexión. Es la configuración. No veo por qué esto es diferente de usar la configuración para bases de datos de control de calidad versus producción. No pones declaraciones en código para eso, ¿verdad?
JimmyJames
Esta es una aplicación que habla con dos bases de datos.
TheCatWhisperer
Creo que no comprende el problema: "tenemos que mantener los datos de los clientes de diferentes países en bases de datos separadas (específicas del país)" No se requiere una sola "instancia" de aplicación para comunicarse con dos bases de datos. Dudo que sean solo dos DB. El OP probablemente quiso decir "eg" cuando escribieron "ie"
JimmyJames
0

Iría con la segunda opción, da menos fricción en el desarrollo y la implementación.

Esto permitirá una mejor escalabilidad y disponibilidad y mejores opciones de implementación de tiempo de inactividad cero, ya que distribuyó su aplicación a 1 (o al menos una) instancia por región en lugar de al menos una para todo el mundo.

A medida que cambien los requisitos, es posible que tenga una lógica comercial más específica de la región y posiblemente también cambios de datos, trataría de dividir el código y sus datos por región, y evitaría compartir la lógica comercial específica de la región (puede terminar compartiendo algún código central).

¿Tener sentido?

Sean Farmar
fuente