Modi per condividere DTO tra microservizi?


33

Il mio scenario è il seguente.

Sto progettando un sistema progettato per ricevere dati da vari tipi di sensori, convertirli e quindi insistere affinché vengano utilizzati in seguito da vari servizi front-end e di analisi.

Sto cercando di progettare ogni servizio in modo che sia il più indipendente possibile, ma ho qualche problema. Il team ha deciso un DTO che vorremmo usare. I servizi rivolti verso l'esterno (destinatari dei dati del sensore) riceveranno i dati nel loro modo unico, quindi li convertiranno in un oggetto JSON (il DTO) e li invieranno al Message Broker. I consumatori dei messaggi sapranno quindi esattamente come leggere i messaggi dei dati del sensore.

Il problema è che sto usando lo stesso DTO in alcuni servizi diversi. Un aggiornamento deve essere implementato in più posizioni. Ovviamente, l'abbiamo progettato in modo tale che alcuni campi extra o mancanti nel DTO qui e non ci siano molti problemi fino a quando i servizi non sono stati aggiornati, ma mi infastidisce ancora e mi fa sentire come se fossi fare un errore. Potrebbe facilmente trasformarsi in mal di testa.

Sto andando a progettare il sistema in modo sbagliato? In caso contrario, quali sono alcuni modi per aggirare questo, o almeno per alleviare le mie preoccupazioni?


Che tipo di DTO stai condividendo e che protocollo stai usando tra i servizi? Va bene condividere, ad esempio, il protofile per gRPC o lo avroschema per Kafka e generare i DTO in entrambi i servizi, ma non condividerei una libreria condivisa tra due progetti.
Vincent Savard,

Stringhe JSON codificate e AMQP. Preferirei non usare nulla di specifico per la lingua.
nbaughman,

Risposte:


38

Il mio consiglio? Non condividere questi DTO tra le applicazioni in nessun tipo di libreria. O almeno non farlo adesso.

Lo so, sembra molto controintuitivo. Stai duplicando il codice, giusto? Ma questa non è una regola aziendale, quindi puoi essere più flessibile.

Il servizio che invia il DTO deve essere rigido nel suo contratto di messaggi, come un'API Rest. Il servizio non può modificare il DTO in modo tale da interrompere gli altri servizi che stanno già consumando le informazioni dal DTO.

Quando viene aggiunto un nuovo campo DTO, si aggiornano gli altri servizi che utilizzano questo DTO solo se hanno bisogno del nuovo campo. Altrimenti, dimenticalo. Utilizzando JSON come tipo di contenuto, hai la flessibilità di creare e inviare nuovi attributi senza interrompere il codice dei servizi che non mappano questi nuovi campi nelle sue attuali versioni di DTO.

Ma se questa situazione ti disturba davvero, puoi seguire la Regola dei tre :

Ci sono due "Regole dei tre" nel riutilizzo: (a) È tre volte più difficile costruire componenti riutilizzabili rispetto ai componenti monouso, e (b) un componente riutilizzabile dovrebbe essere provato in tre diverse applicazioni prima che sia sufficientemente generale accettare in una libreria di riutilizzo.

Quindi, prova ad aspettare un po 'di più prima di condividere questo DTO tra i servizi.


1
Davvero apprezzato. Questa è davvero una delle pochissime preoccupazioni importanti che devo andare avanti. Non abbastanza per tenermi sveglio la notte, ma abbastanza per preoccuparmi.
nbaughman,

4
DTO duplicati (in servizi diversi e molto indipendenti) non violano il DRY. Questo è tutto.
Laiv

3
Presumibilmente quindi non c'è motivo di non copiare il codice sorgente DTO direttamente da un progetto a un altro, come un'operazione una tantum, anche se probabilmente tutte le parti non richieste nel nuovo progetto dovrebbero essere eliminate.
bdsl,

1
Anche un intero servizio potrebbe essere eliminato senza causare grossi problemi all'intero sistema. Idealmente.
Laiv

4
Per chiarire l'essenza della risposta, quando si sviluppano microservizi, ogni servizio dovrebbe essere sviluppato come se non conoscessero gli altri servizi, ad eccezione dei contratti effettivi che potrebbe richiedere.
Jonathan van de Veen,

12

Per quanto riguarda i microservizi, anche i cicli di vita dei servizi dovrebbero essere indipendenti. *

Diversi SLDC e diversi team di sviluppo

in un vero sistema MS, potrebbero esserci diversi team coinvolti nello sviluppo dell'ecosistema, ciascuno dei quali responsabile di uno o più servizi. A loro volta, questi team potrebbero trovarsi in diversi uffici, città, paesi, piani ... Forse non si conoscono nemmeno, ciò che rende molto difficile la condivisione di conoscenza o codice (se possibile). Ma questo potrebbe essere molto conveniente perché il codice condiviso implica anche una sorta di ragionamento condiviso e qualcosa di importante da ricordare è che, qualunque cosa abbia senso per un team specifico, non deve farlo per un altro team. Ad esempio, dato il cliente DTO , potrebbe essere diverso a seconda del servizio in gioco, poiché i clienti vengono interpretati (o visti) in modo diverso da ciascun servizio.

Esigenze diverse, tecnologie diverse

Gli SLDC isolati consentono inoltre ai team di scegliere lo stack più adatto alle proprie esigenze. L'imposizione di DTO implementati in una tecnologia specifica limita la capacità dei team di scegliere.

I DTO non sono né regole commerciali né contratti di servizi

Quali DTO sono veramente? Oggetti semplici senza altro obiettivo se non quello di spostare i dati da un lato all'altro. Sacchi di getter e setter. Non è il tipo di "conoscenza" che vale la pena riutilizzare, in generale perché non c'è alcuna conoscenza. La loro volatilità li rende anche cattivi candidati per l'accoppiamento.

Contrariamente a quanto affermato da Dherik, deve essere possibile che un servizio modifichi i propri DTO senza dover fare contemporaneamente cambiare altri servizi. I servizi dovrebbero essere lettori tolleranti, scrittori tolleranti e non tolleranti . Altrimenti, causano l'accoppiamento in modo tale da rendere insensata l'architettura del servizio. Ancora una volta, e contrariamente alla risposta di Dherik, se tre servizi necessitano esattamente degli stessi DTO, è probabile che qualcosa sia andato storto durante la decomposizione dei servizi.

Affari diversi, interpretazioni diverse

Mentre potrebbero esserci (e ci saranno) concetti trasversali tra i servizi, ciò non significa che dobbiamo imporre un modello canonico per costringere tutti i servizi a interpretarli allo stesso modo.

Argomento di studio

Supponiamo che la nostra azienda abbia tre dipartimenti, servizio clienti , vendite e spedizioni . Di 'a ciascuna di queste versioni uno o più servizi.

Il servizio clienti, grazie al suo linguaggio di dominio , implementa servizi intorno al concetto di clienti, in cui i clienti sono persone . Ad esempio, i clienti sono modellati come nome , cognome , età , sesso , e-mail , telefono , ecc.

Ora diciamo che le vendite e le spedizioni modellano i loro servizi anche in base alle rispettive lingue di dominio. In queste lingue, appare anche il concetto di cliente, ma con una sottile differenza. Per loro, i clienti non sono (necessariamente) persone . Per le vendite , i clienti sono un numero di documento una carta di credito e un indirizzo di fatturazione , per la spedizione anche un nome completo e un indirizzo di spedizione .

Se forziamo le vendite e le spedizioni ad adottare il modello di dati canonico del servizio clienti , li stiamo costringendo a gestire i dati non necessari che potrebbero finire per introdurre complessità inutili se devono mantenere l'intera rappresentazione e mantenere i dati dei clienti in sintonia con il servizio clienti .

Link correlati


* Qui è dove pongono i punti di forza di questa architettura


Grazie! I casi studio sono in realtà ciò che mi ha aiutato a determinare se condividere i DTO o meno. Ora sono sicuro del perché non volevo condividerli.
Igor

8

Sto cercando di progettare ogni servizio per essere il più indipendente possibile

Dovresti pubblicare eventi . Gli eventi sono un certo tipo di messaggi che rappresentano un fatto solido su qualcosa che è accaduto in un determinato momento.

Ogni servizio dovrebbe avere una responsabilità ben definita e dovrebbe avere la responsabilità di pubblicare gli eventi relativi a tale responsabilità.

Inoltre, desideri che i tuoi eventi rappresentino eventi relativi al business, non eventi tecnici. Ad esempio, preferire l' OrderCancelledevento a un OrderUpdatedcon status: "CANCELLED".

In questo modo, quando un servizio deve reagire a un ordine annullato, deve solo ascoltare quel particolare tipo di messaggio, che trasporta solo dati rilevanti per quell'evento. Ad esempio un OrderCancelledprobabilmente ha solo bisogno di un order_id. Qualunque servizio che debba reagire a questo ha già archiviato tutto ciò che è necessario sapere sull'ordine nel proprio archivio dati.

Ma se il servizio avesse solo OrderUpdatedeventi da ascoltare, avrebbe bisogno di interpretare il flusso degli eventi, e ora dipendeva dall'ordine di consegna per concludere correttamente quando un ordine veniva annullato.

Nel tuo caso, tuttavia, come il vostro sono la pubblicazione dei dati del sensore, potrebbe avere senso per avere un servizio, intercettare gli eventi e pubblicare un nuovo flusso di "eventi di business", ad esempio TemperatureThresholdExceeded, TemperatureStabilised.

E fai attenzione a creare troppi microservizi. I microservizi possono essere un ottimo modo per incapsulare la complessità, ma se non scopri i limiti del servizio adeguati, la tua complessità è nell'integrazione del servizio. E questo è un incubo da mantenere.

È meglio avere servizi troppo pochi, troppo grandi, piuttosto che avere troppi servizi troppo piccoli.


Sono assolutamente d'accordo. I dati del sensore arrivano direttamente in un microservizio che analizza il messaggio e lo trasforma in un formato concordato a livello di organizzazione prima di pubblicarlo sul broker. Avremo alcuni servizi che leggono il messaggio e lo persistono in un database, e altri che eseguono analisi del messaggio e fanno le proprie cose con esso. Ogni servizio, per sua natura, non ha molto da fare, portando a servizi (si spera) piuttosto semplici.
nbaughman,

2
@ Nickdb93 - Nel tuo caso, mentre stai pubblicando i dati dei sensori, potrebbe avere senso avere un servizio, ascoltare gli eventi e pubblicare un nuovo flusso di "eventi aziendali", ad esempio TemperatureThresholdExceeded, TemperatureStabilised. (aggiunto alla risposta)
Pete,
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.