È una cattiva pratica per i servizi condividere un database in SOA?


17

Di recente ho letto Hohpe e Woolf's Enterprise Integration Patterns, alcuni dei libri di Thomas Erl su SOA e guardato vari video e podcast di Udi Dahan et al. su sistemi CQRS ed Event Driven.

I sistemi nel mio posto di lavoro soffrono di un elevato accoppiamento. Sebbene teoricamente ogni sistema abbia un proprio database, tra loro c'è molto da unire. In pratica questo significa che esiste un enorme database che tutti i sistemi usano. Ad esempio, esiste una tabella di dati dei clienti.

Gran parte di ciò che ho letto sembra suggerire la denormalizzazione dei dati in modo che ogni sistema utilizzi solo il suo database e qualsiasi aggiornamento a un sistema venga propagato a tutti gli altri tramite la messaggistica.

Ho pensato che questo fosse uno dei modi per far rispettare i confini della SOA - ogni servizio dovrebbe avere il suo database, ma poi ho letto questo:

/programming/4019902/soa-joining-data-across-multiple-services

e suggerisce che questa è la cosa sbagliata da fare.

La segregazione dei database sembra un buon modo per disaccoppiare i sistemi, ma ora sono un po 'confuso. È una buona strada da percorrere? Si consiglia mai di separare un database, ad esempio un servizio SOA, un contesto DDD Bounded, un'applicazione, ecc.?


La domanda originale che colleghi è errata. La domanda in sé è sbagliata, poiché sfuggono alla maggior parte delle risposte. La SOA non consiste nel dividere una singola applicazione in servizi discreti e nel partizionare i loro dati.
Jeremy,

Capisco che la domanda è sbagliata, sono state le risposte a farmi rivalutare il mio pensiero.
Paul T Davies,

Penso che i servizi debbano essere accoppiati
B Seven,

Risposte:


12

Il disaccoppiamento funziona solo se c'è davvero separazione. Considera se hai un sistema di ordinazione:

  • Tabella: CLIENTE
  • Tabella: ORDINA

Se questo è tutto ciò che hai, non c'è motivo di separarli. D'altra parte, se hai questo:

  • Tabella: CLIENTE
  • Tabella: ORDINA
  • Tabella: CUSTOMER_NEWSLETTER

Quindi potresti sostenere che ORDER e CUSTOMER_NEWSLETTER fanno parte di due moduli totalmente separati (ordini e marketing). Forse ha senso spostarli in database separati (uno per ogni tabella) ed entrambi i moduli condividono l'accesso alla tabella CUSTOMER comune nel proprio database.

In questo modo stai semplificando ogni modulo, ma stai aumentando la complessità del tuo livello dati. Man mano che la tua applicazione diventa sempre più grande, vedo un vantaggio nel separare. Ci saranno sempre più "isole dati" che non hanno alcuna relazione reciproca. Tuttavia, ci saranno sempre alcuni dati che tagliano trasversalmente tutti i moduli.

La decisione di inserirli in diversi database fisici si baserebbe in genere su vincoli del mondo reale come la frequenza dei backup, le restrizioni di sicurezza, la replica in diverse aree geografiche, ecc. Non separerei le tabelle in diversi database fisici solo per motivi di separazione. Questo può essere gestito in modo più semplice con diversi schemi o viste.


5
-1. Dovrebbero trovarsi in database separati solo se c'è un motivo per metterli lì. Devi "tirarne fuori qualcosa" perché sicuramente rende la tua app più complessa.
scottschulthess,

1
Penso che valga la pena porre l'accento sull'importanza di separare le due aree di funzionalità a livello di dati (se si utilizzano schemi separati o qualcos'altro). Ogni modulo dovrebbe accedere ai dati dell'altro modulo solo tramite l'API dell'altro modulo - questo è simile ai principi di incapsulamento OO. Vale a dire non condivido uno schema tra più moduli. Inoltre, consiglierei contro le visualizzazioni, preferendo invece esporre i dati tramite. un'API.
Chris Snow,

@scottschulthess sì, devi valutare il costo della complessità e se non ne vale la pena non puoi semplicemente dividerlo in servizi. Dividere ma utilizzando un database condiviso che ho trovato è la peggiore delle 3 opzioni.
Adamantish,

8

Dove lavoro, abbiamo un ESBa cui sono collegate 6 diverse applicazioni (o dovrei dire "endpoint"). Queste 6 applicazioni funzionano con 3 diversi schemi Oracle su 2 istanze di database. Alcune di queste applicazioni coesistono nello stesso schema non perché sono correlate ma perché la nostra infrastruttura di database è gestita da un provider esterno e ottenere un nuovo schema richiede solo un'eternità (inoltre, non abbiamo accesso DBA ovviamente) ... impiega davvero tanto tempo che a un certo punto abbiamo pensato di riutilizzare "temporaneamente" uno schema esistente per poter continuare lo sviluppo. Per applicare la "separazione" dei dati, i nomi delle tabelle sono preceduti, ad esempio "CST_" per il cliente. Inoltre, dobbiamo lavorare con uno schema che per alcuni motivi validi non possiamo cambiare in modo assoluto ... È strano, lo so. Certo, come sempre accade, "temporaneamente"

Le nostre diverse applicazioni si collegano al rispettivo schema di database e funzionano con i propri pacchetti PL / SQL e ci vietiamo assolutamente di interagire direttamente con tabelle / dati esterni al nostro dominio di applicazione.

Quando una delle applicazioni connesse all'ESB necessita di informazioni al di fuori del proprio dominio, chiama il relativo servizio sull'ESB per ottenere i dati, anche se tali informazioni si trovano effettivamente nello stesso schema, richiedendo in teoria solo una piccola istruzione di join in una delle richieste SQL .

Lo facciamo per poter dividere il nostro dominio di applicazione in diversi schemi / database e per far sì che i servizi sull'ESB funzionino correttamente anche quando accade (è Natale presto, stiamo mettendo le dita)

Ora, questo può sembrare strano e terribile dall'esterno, ma ci sono ragioni per questo e volevo solo condividere questa esperienza concreta per mostrarti che uno o più database non sono così importanti. Aspetta, lo è! , per molte ragioni (+1 per Scott Whitlock, vedi l'ultimo paragrafo sul backup e tale che mya ti porti nei guai) Ma è altrettanto importante che i tuoi servizi SOA siano progettati correttamente, almeno questa è la mia opinione, e io non sono un DBA. In definitiva, tutti i tuoi database appartengono al tuo "datawarehouse aziendale", giusto?

Infine, non riformulerò l'ultimo paragrafo di Scott Whitlock, in particolare questo

Non separerei le tabelle in diversi database fisici solo per motivi di separazione.

è davvero molto importante. Non farlo se non c'è motivo.


8

Ho visto i peggiori incubi possibili nell'architettura software a causa dell'integrazione dei dati e la migliore arma contro questo tipo di pasticcio che ho incontrato finora contesti confinati in stile DDD. Che non è molto lontano da "SOA fatto bene", in un certo senso.

Tuttavia, i dati stessi non sono il modo migliore per attaccare il problema. Uno dovrebbe concentrarsi sul comportamento previsto / necessario e portare i dati dove sono importanti. Potremmo finire per avere qualche duplicazione in questo modo, ma questo non è normalmente un problema rispetto ai blocchi per l'evoluzione del sistema quasi sempre associati alle architetture integrate nei dati.

Per dirla in parole povere: se stai cercando sistemi debolmente accoppiati, non rimanere accoppiato ai dati. Scegli i sistemi incapsulati nel weel e un canale di comunicazione ben strutturato nel mezzo, fungendo da "lingua franca".


1
E ... rispondendo direttamente alla domanda del titolo: "Sì, considererei una pratica rischiosa condividere un database in una SOA", Se sembra la cosa più ragionevole da fare, probabilmente c'è qualche grave difetto di progettazione.
ZioBrando,

7

Disaccoppiare i database e mantenere coerenti i dati tra loro è un compito di livello esperto. È molto facile sbagliarsi e finire con i problemi dei duplicati ecc., Che l'attuale sistema è progettato per evitare. Francamente, prendere un sistema funzionante e farlo è praticamente una garanzia di introdurre nuovi bug per nessun valore reale per gli utenti.


1

Se fatto correttamente, separare le preoccupazioni aziendali in database diversi (o almeno schemi diversi) è una virtù .

Si prega di consultare la descrizione di Martin Fowler del modello CQRS :

Man mano che le nostre esigenze diventano più sofisticate, ci allontaniamo costantemente dal [trattamento di un sistema informativo come un archivio dati CRUD] ... Il cambiamento introdotto da CQRS è quello di suddividere quel modello concettuale in modelli separati per l'aggiornamento e la visualizzazione ... C'è spazio per notevoli variazioni Qui. I modelli in memoria possono condividere lo stesso database, nel qual caso il database funge da comunicazione tra i due modelli. Tuttavia, possono anche utilizzare database separati , creando efficacemente il database del lato query da un ReportingDatabase in tempo reale. In questo caso è necessario un meccanismo di comunicazione tra i due modelli o i loro database.

E principi architettonici di NServiceBus :

Separazione query comando

Una soluzione che evita questo problema separa i comandi e le query a livello di sistema, anche al di sopra di quello di client e server. In questa soluzione esistono due "servizi" che si estendono sia al client che al server: uno responsabile dei comandi (creazione, aggiornamento, eliminazione), l'altro responsabile delle query (lettura). Questi servizi comunicano solo tramite messaggi: uno non può accedere al database dell'altro ...

E segregazione di responsabilità di comando e query (CQRS)

Segregazione della responsabilità di comando e query

La maggior parte delle applicazioni legge i dati più frequentemente di quanto scriva i dati. Sulla base di tale affermazione, sarebbe una buona idea creare una soluzione in cui è possibile aggiungere facilmente più database da cui leggere, giusto? E se avessimo creato un database dedicato solo alla lettura? Anche meglio; cosa succede se progettiamo il database in modo che sia più veloce da leggere da esso? Se progettate le vostre applicazioni in base ai modelli descritti nell'architettura CQRS, avrete una soluzione che è scalabile e veloce nella lettura dei dati.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.