2011-09-25 5 views
6

Sono stato incaricato di creare un'applicazione multi-tenant aziendale. Ha un BLL Java/Glassfish che utilizza servizi Web SOAP e un backend PostgreSQL. Ogni inquilino ha il proprio database, quindi (almeno nel mio caso) "multi-tenant" significa supportare più database per server applicativo.Implementazione di multi-tenancy per un'applicazione aziendale matura

L'appserver single-tenant corrente inizializza un pool di connessioni C3P0 con una stringa di connessione che ottiene da un file di configurazione. Il mio pensiero è che ora ci sarà bisogno di un pool di connessioni per client/database servito dal server delle app.

Dopo che un utente ha effettuato l'accesso, è possibile collegarlo al pool di connessioni corretto controllando il tenant. Il mio problema principale è come arrivare a questo punto: quando un utente accede per la prima volta, viene interrogata la tabella User del backend e viene pubblicato l'oggetto User corrispondente. Sembra che avrò bisogno di sapere quale database usare con solo un nome utente con cui lavorare.

La mia unica idea decente è che ci sarà bisogno di un database "di configurazione" - un database centralizzato per la gestione delle informazioni dei titolari come le stringhe di connessione. Il BLL può interrogare questo database per informazioni sufficienti per inizializzare i pool di connessione necessari. Ma dal momento che ho solo un nome utente con cui lavorare, sembra che avrei bisogno anche di una ricerca centralizzata del nome utente, in altre parole una tabella UserName con una chiave esterna per la tabella Tenant.

È qui che il mio piano di progettazione inizia ad annusare, dandomi dei dubbi. Ora avrei le informazioni dell'utente in due database separati, che dovrebbero essere mantenuti in modo sincrono (aggiunte dell'utente, aggiornamenti e cancellazioni). Inoltre, ora i nomi utente dovrebbero essere unici a livello globale, mentre prima dovevano essere unici per inquilino.

Ho il forte sospetto che io stia reinventando la ruota o che ci sia almeno un'architettura migliore possibile. Non ho mai fatto questo genere di cose prima d'ora, né qualcuno nella mia squadra, quindi la nostra ignoranza. Sfortunatamente l'applicazione fa un piccolo uso delle tecnologie esistenti (ad esempio, l'ORM è stato home-roll), quindi il nostro percorso potrebbe essere difficile.

sto chiedendo quanto segue:

  • Critica del mio piano di progettazione esistenti, e suggerimenti per migliorare o rielaborare l'architettura.
  • Raccomandazioni di tecnologie esistenti che forniscono una soluzione a questo problema. Spero in qualcosa che possa essere facilmente inserito a fine partita, anche se potrebbe non essere realistico. Ho letto su jspirit, ma ho trovato poche informazioni su di esso - qualsiasi feedback su di esso o altri framework sarà utile.

UPDATE: La soluzione è stata implementata con successo e distribuito, e ha superato il test iniziale. Grazie a @mikera per la sua risposta utile e rassicurante!

risposta

5

Alcuni pensieri veloci:

  • sarà sicuramente bisogno di una qualche forma di indice gestione utente condiviso (altrimenti non si può associare un account di accesso client con la giusta istanza di database di destinazione). Comunque suggerirei di renderlo molto leggero e di usarlo solo per il login iniziale. L'oggetto utente può ancora essere estratto dal database specifico del client una volta determinato quale sia il database.
  • È possibile rendere la chiave primaria [clientID, nome utente] in modo che i nomi utente non debbano essere univoci tra i client.
  • Oltre a questo strato di indice utente sottile, vorrei mantenere la maggior parte delle informazioni dell'utente in cui si trova nei database specifici del client. Refactoring questo ora probabilmente sarà troppo dirompente, si dovrebbe ottenere la capacità multi-tenant di base prima di lavorare.
  • È necessario mantenere l'indice condiviso in sincronizzazione con i singoli database del client. Ma non penso che dovrebbe essere troppo difficile. Puoi anche "testare" la sincronizzazione e correggere eventuali errori con un lavoro batch, che può essere eseguito durante la notte o su richiesta del tuo DBA se qualcosa dovesse mai andare fuori sincrono. Tratterei i database dei client come master e usarli per ricostruire l'indice utente condiviso su richiesta.
  • Nel corso del tempo si può refactoring verso un livello di gestione degli utenti pienamente condiviso (e anche, alla fine, pienamente condiviso database di clienti, se volete. Ma salvare questo per un futuro di iterazione .....
+0

+1 Questa risposta è rassicurante: il database di configurazione sarà molto leggero, come dici tu, utilizzato solo durante la ricerca di init e username del pool di connessioni. –

Problemi correlati