2014-09-01 18 views
36

Se si utilizza un'architettura microservizi nella propria organizzazione, è possibile condividere la configurazione tramite zookeeper o equivalente. Tuttavia, come dovrebbero i vari servizi condividere uno schema db comune? costanti comuni? e utilità comuni?Condivisione di codice e schema tra microservizi

Un modo sarebbe quello di mettere tutte le microservices nello stesso repository di codice, ma che contraddirebbe il disaccoppiamento che viene fornito con microservices ...

altro modo sarebbe quello di avere ogni Microservice essere completamente indipendente, tuttavia, che causerebbe la duplicazione del codice e la duplicazione dei dati nei database separati che ciascun microservizio avrebbe dovuto contenere.

Un altro modo sarebbe quello di implementare microservices funzionali con nessun contesto \ Stato, ma che non è di solito realistico e spingerebbe l'architettura ad avere un hub centrale che mantiene contesto \ Stato e un sacco di traffico da \ ad esso.

Quale sarebbe un modo scalabile, efficiente, pratico e auspicabilmente bello per condividere codice e schema tra i microservizi?

+4

Mi piacerebbe avere risposte realistiche e pratiche. Si prega di astenersi da esitazioni dogmatiche. – Jonathan

risposta

4

Dalla mia esperienza di progetto

Condividere un WSDL quando si utilizza SOAP (non il codice di modello di servizio, dal momento che essi dovrebbero essere generati dal WSDL). Quando si utilizza REST, disporre di modelli distinti (copia sì ma non condivisione) per client e server. Non appena il secondo o il terzo consumatore entrano in gioco, ti troverai nei guai. Tienili disaccoppiati. Il funzionamento e l'utilizzo di un servizio sono cambiati nel mio passato più spesso rispetto alle strutture di dati. Un altro cliente desidera utilizzare il servizio o una seconda versione deve essere utilizzata allo stesso tempo.

Alcune riflessioni aggiuntive

di condivisione è parziale contradictive alla scalabilità. Condividi-niente e share-some/share-all hanno entrambi pro e contro. Condividere nulla ti dà la massima flessibilità in qualsiasi momento. I microservizi sono componenti indipendenti che forniscono servizi di dominio particolari.

La condivisione di modelli di dati del dominio aziendale è un modello comune (http://www.ivarjacobson.com/resources/resources/books/#object%20oriented%20software) che impedisce le duplicazioni dello stesso. Poiché i microservizi dividono e conquistano le parti aziendali, potrebbe diventare difficile condividere qualcosa del modello di dati del dominio aziendale.

I microservizi comunicano tra loro, quindi comprendo la necessità di condividere questi modelli di dati di comunicazione (principalmente basati su HTTP). La condivisione di questi modelli di dati potrebbe essere OK nel caso in cui si disponga di una mappatura uno a uno tra fornitore di servizi e consumatore. Non appena si hanno più consumatori per un servizio che richiede modelli/campi diversi all'interno del modello, diventa difficile.

23

Per quanto riguarda il codice comune, è consigliabile utilizzarlo in un sistema di imballaggio. Quindi se usi Java, usa Maven, se usi Ruby poi Gems, se python poi pypi ecc. Idealmente un sistema di packaging aggiunge poco attrito, quindi potresti avere un repository (diciamo, git) per una lib comune (o più comuni -lib per argomenti diversi) e pubblica i propri artefatti attraverso un repository di risorse (ad es. private maven/gems/pypi). Quindi al microservice si aggiunge la dipendenza dalla libs richiesta. Il riutilizzo del codice è semplice. In alcuni casi i sistemi di imballaggio aggiungono un po 'di attrito (uno per uno), quindi si potrebbe preferire l'uso di un singolo repository git per tutto e una configurazione di progetto multi-modulo. Non è pulito come il primo approccio, ma funziona bene e non male. Altre opzioni sono usare git submodule (meno desiderato) o git subtree (meglio) per includere il codice sorgente in un singolo repository "principale".

Riguardo allo schema: se si desidera riprodurre dal libro, ogni microservizio dispone di un proprio database. Non si toccano i dati l'uno dell'altro. Questo è un approccio molto modulare che a prima vista sembra aggiungere un certo attrito al tuo processo, ma alla fine penso che mi ringrazierai. Permetterà una rapida iterazione sui tuoi microservizi, ad esempio potresti voler sostituire un'implementazione del database con un'altra implementazione del database per un servizio specifico. Immagina di farlo quando tutti i tuoi servizi utilizzano lo stesso database! Buona fortuna con questo ... Ma se ogni singolo servizio utilizza il proprio database, il servizio astrae correttamente il database (ad esempio non accetta query SQL come chiamate API ad esempio ;-)), quindi la modifica di mysql in Cassandra diventa improvvisamente fattibile. Ci sono altri aspetti positivi ad avere basi di dati completamente isolati, per esempio il carico e lo scaling, scoprire i colli di bottiglia, la gestione ecc

Così, in breve - codice comune (utilities, costanti ecc) - utilizzare un sistema di imballaggio o qualche codice sorgente linkage come git-tree

Database: non si tocca il mio, io non tocco il tuo. Questo è il modo migliore per aggirare questo.

HTH, Ran.

+1

Vuoi avere un'autenticazione separata per gli utenti db per microservice? – Jonathan

+1

Stai parlando di utenti dell'applicazione reali? Se è così - allora certamente no, usa un servizio di autenticazione/autorizzazione per quello. Se ti riferisci a "utenti API" ad es. come mantenere il microservice sicuro nella tua rete quindi di solito uso un firewall ecc. ma non è un modo super sicuro, sono sicuro che ci sono soluzioni migliori per questo. – Ran

+1

Un equivoco è che un'applicazione "monolitica" deve essere internamente caotica senza alcuna modularizzazione. Non è vero, ad es. il kernel di Linux è monolitico. Un SO microkernel costringerà ogni servizio ad essere nei propri processi; ma questa architettura è fuori dal gusto a causa del sovraccarico. Con la modularizzazione/refactoring, l'esempio di migrazione parziale di DB che citi è possibile anche in monolitico. Microservice non è l'unico modo per la consegna o il disaccoppiamento continui. Potrebbe non essere davvero così efficace in entrambi. –

10

L'approccio "più puro", ovvero quello che ti dà la minore quantità di accoppiamento, è quello di non condividere alcun codice.

Se si scopre che due servizi (chiamarli A e B) hanno bisogno la stessa funzionalità, le opzioni sono:

  • Spalato, se fuori come un servizio di C separato, in modo A e B possono utilizzare C
  • stringere i denti e duplicare il codice

se questo può sembrare scomodo, si evita il problema (non raro) di creare una "utilità" o o la libreria "comune" "infrastruttura", che ognuno dipende, e che è quindi davvero difficile aggiornarlo e cambiarlo (cioè quale indirettamente accoppia es i servizi).

In pratica, come al solito, è un compromesso.

  • Se la funzionalità condivisa è notevole, sceglierei un servizio separato.
  • Se sono solo costanti, una libreria condivisa potrebbe essere la soluzione migliore. Devi essere molto attento alla retrocompatibilità, però.
  • Per i dati di configurazione, è possibile anche implementare un servizio specifico, eventualmente utilizzando una tecnologia esistente come LDAP.
  • Infine, per un codice semplice che è probabile che si evolva in modo indipendente, solo la duplicazione potrebbe essere la soluzione migliore.

Tuttavia, ciò che è meglio dipenderà dalla situazione e dal problema specifici.

+2

+1. Se hai bisogno di un codice di utilità condiviso, significa che hai alcune convenzioni comuni che i microservizi devono seguire. Ad esempio, algoritmo di calcolo CRC personalizzato. In questo caso, ogni microsevice deve avere la propria implementazione della convenzione. C'è una regola pratica: pensa a tutti i tuoi microservizi mentre vengono implementati su piattaforme/strumenti/lingue differenti. – neleus

0

Per quanto riguarda il principio ISP (principio di segregazione dell'interfaccia) i client dovrebbero dipendere dall'interfaccia e non dalle implementazioni. Suggerirei se è possibile condividere le interfacce e non implementarle in questo modo sarebbe meglio rendere il sistema disgiunto dall'implementazione.

+0

Non si tratta di ISP ma di dipendenza da inversione. – Tunceren

Problemi correlati