2011-09-25 14 views
6

Se me ha encomendado la tarea de hacer una aplicación empresarial multi-tenant. Tiene un BLL de Java/Glassfish utilizando servicios web SOAP y un backend de PostgreSQL. Cada inquilino tiene su propia base de datos, por lo que (en mi caso al menos) "multi-tenant" significa soportar múltiples bases de datos por servidor de aplicaciones.Implementación de multi-tenancy para una aplicación empresarial madura

El servidor de aplicaciones de un inquilino actual inicializa un grupo de conexiones C3P0 con una cadena de conexión que obtiene de un archivo de configuración. Mi opinión es que ahora será necesario que haya un grupo de conexiones por cliente/base de datos atendida por el servidor de aplicaciones.

Una vez que un usuario ha iniciado sesión, puedo asignarlo al grupo de conexiones correcto buscando su inquilino. Mi principal problema es cómo llegar hasta aquí: cuando un usuario inicia sesión por primera vez, se consulta la tabla User del servidor y se muestra el objeto correspondiente User. Parece que necesitaré saber qué base de datos usar con solo un nombre de usuario para trabajar.

Mi única idea decente es que tendrá que haber una base de datos "config", una base de datos centralizada para administrar la información del inquilino, como las cadenas de conexión. El BLL puede consultar esta base de datos para obtener suficiente información para inicializar los grupos de conexiones necesarios. Pero dado que solo tengo un nombre de usuario para trabajar, parece que necesitaría una búsqueda de nombre de usuario centralizada también, en otras palabras, una tabla UserName con una clave externa a la tabla Tenant.

Aquí es donde mi plan de diseño comienza a oler, lo que me da dudas. Ahora tendría información de usuario en dos bases de datos separadas, que deberían mantenerse de forma síncrona (adiciones de usuarios, actualizaciones y eliminaciones). Además, los nombres de usuario tendrían que ser globalmente únicos, mientras que antes solo tenían que ser únicos por inquilino.

Sospecho fuertemente que estoy reinventando la rueda, o que hay al menos una mejor arquitectura posible. Nunca he hecho este tipo de cosas antes, ni tiene a nadie en mi equipo, de ahí nuestra ignorancia. Desafortunadamente, la aplicación hace poco uso de las tecnologías existentes (por ejemplo, el ORM fue rodado a casa), por lo que nuestro camino puede ser difícil.

lo que estoy pidiendo lo siguiente:

  • La crítica de mi plan de diseño ya existente, y sugerencias para mejorar o volver a trabajar la arquitectura.
  • Recomendaciones de las tecnologías existentes que proporcionan una solución a este problema. Estoy esperando algo que pueda ser conectado fácilmente al final del juego, aunque esto puede ser poco realista. He leído acerca de jspirit, pero he encontrado poca información sobre él, cualquier comentario sobre él u otros marcos será útil.

ACTUALIZACIÓN: La solución ha sido implementado y desplegado con éxito y ha superado la prueba inicial. ¡Gracias a @mikera por su respuesta útil y tranquilizadora!

Respuesta

5

Algunos pensamientos rápidos:

  • que sin duda necesita algún tipo de índice de gestión de usuario compartida (de lo contrario no se puede asociar un inicio de sesión de cliente con el derecho instancia de base de destino). Sin embargo, sugiero que sea muy liviano y solo lo use para iniciar sesión por primera vez. Su objeto Usuario aún se puede extraer de la base de datos específica del cliente una vez que haya determinado qué base de datos es esta.
  • Puede crear la clave principal [ID de cliente, nombre de usuario] para que los nombres de usuario no tengan que ser únicos entre los clientes.
  • Aparte de esta delgada capa de índice de usuario, me gustaría mantener la mayoría de la información del usuario donde se encuentra en las bases de datos específicas del cliente. Refaccionar esto ahora mismo probablemente sea demasiado perturbador, primero debe obtener la capacidad básica de múltiples inquilinos.
  • Necesitará mantener el índice compartido en sincronización con las bases de datos de clientes individuales. Pero no creo que eso sea demasiado difícil. También puede "probar" la sincronización y corregir cualquier error con un trabajo por lotes, que se puede ejecutar de la noche a la mañana o por su DBA bajo demanda si alguna vez se sale de sincronización. Trataría las bases de datos del cliente como maestro y las usaría para reconstruir el índice de usuarios compartidos a pedido.
  • Con el tiempo se puede refactorizar hacia una capa de gestión de usuario totalmente compartida (e incluso en el final totalmente compartida bases de datos de clientes, si quieres. Pero guardar esta iteración para un futuro .....
+0

1 Esta respuesta es tranquilizadora: la base de datos de configuración será muy liviana, como dices, solo se usa durante el inicio del grupo de conexiones y la búsqueda de nombre de usuario. Excelente punto sobre un trabajo por lotes nocturno para limpiar/informar cabos sueltos. –

Cuestiones relacionadas