I microservizi dovrebbero parlare tra loro?

18

Sto progettando un'applicazione che utilizza Micro-Services e non sono sicuro sul miglior meccanismo da utilizzare per raccogliere dati da più servizi.

Credo che ci siano due opzioni:

  • Integrare un meccanismo di comunicazione "interservizi" che consente ai servizi di parlare direttamente. Il gateway API chiamerebbe un singolo servizio, che quindi chiama altri servizi per raccogliere i dati, prima di restituire la risposta consolidata al gateway API. L'API restituisce quindi la risposta al chiamante. (Questo dovrebbe essere chiamate sincrone quando la chiamata al servizioB richiede la risposta dal servizio A. I. Seperate Person and Address Services.)
  • Chiedere al gateway API di chiamare ciascun servizio direttamente e consolidare i dati all'interno dell'API prima di restituire la risposta.

Mi sto appoggiando alla seconda opzione, in quanto i servizi che si comunicano tra loro introdurranno l'accoppiamento, nel qual caso potrei anche solo progettare un'applicazione monolitica. Tuttavia, ci sono alcuni seri inconvenienti che riesco a ricambiare con questa opzione:

  • Se l'API esegue più chiamate su più servizi, aumenta il carico sul server API, soprattutto quando alcune di queste chiamate stanno bloccando.

  • Questo metodo significherebbe che l'API deve essere "a conoscenza" di ciò che l'applicazione sta tentando di fare (IE Logic dovrebbe essere programmata nell'API per gestire a turno la chiamata dei servizi, e quindi per consolidare il dati), piuttosto che agire come un "endpoint" stupido per i micro-servizi.

Mi piacerebbe sapere qual è l'approccio standard a questo problema e se c'è un'altra terza opzione che mi manca?

    
posta KidCode 16.10.2016 - 12:59
fonte

4 risposte

15

In generale, sconsiglio di fare in modo che i microservizi facciano una comunicazione sincrona tra loro, il grosso problema è l'accoppiamento, significa che i servizi sono ora accoppiati l'uno all'altro, se uno di essi fallisce il secondo è ora completamente o parzialmente disfunzionale.

Vorrei fare una chiara distinzione tra operazioni di cambio di stato e operazioni di lettura (CQS Separazione delle query di comando ). Per le operazioni di cambio di stato, utilizzerei una sorta di infrastruttura di messaggistica e andrei a fuoco e dimenticherò. Per le query utilizzeresti la comunicazione di risposta alla richiesta sincrona e potresti utilizzare un'API http o semplicemente andare direttamente al tuo archivio dati.

Se utilizzi la messaggistica, puoi anche consultare la pubblicazione subscribe per la raccolta di eventi tra i servizi.

Un altro punto da considerare è la condivisione dei dati (transazionale) (al contrario delle viste di sola lettura) se esponi il tuo stato interno il lettore potrebbe ottenere lo stato sbagliato dei tuoi dati, o la versione sbagliata, e potrebbe bloccare anche i tuoi dati ?

Ultimo ma non meno importante, prova a fare tutto il possibile per mantenere i tuoi servizi autonomi (almeno a livello logico).

Spero che questo abbia un senso.

    
risposta data 17.10.2016 - 19:22
fonte
7

Dipende dal motivo per cui hai bisogno di quei dati. Se è per l'interfaccia utente, che è perfettamente a posto. Inoltre, è il modo in cui dovrebbe essere. Chris Richardson ha una bella spiegazione di questo concetto , e Sam Newman ha un grande articolo su un concetto molto simile chiamato Backends for Frontends .

Ma se ne hai bisogno per un po 'di logica, è probabile che i limiti del servizio siano sbagliati.

Ci sono diverse caratteristiche che il buon senso ci dice i nostri servizi dovrebbero possedere . Sono:

  1. Accoppiamento basso. Se apporti alcune modifiche al servizio A, non vuoi che influenzino il servizio B.
  2. Alta coesione. Se è necessario implementare alcune funzionalità, si desidera che il minor numero possibile di servizi sia interessato.
  3. Alta autonomia. Se alcuni servizi falliscono, non vuoi che l'intero sistema sia inattivo.
  4. Corretta granularità. Non vuoi che i tuoi servizi siano troppo chiacchieroni, dal momento che la tua rete è più una cosa complessa di quanto tu possa pensare.
  5. I servizi dovrebbero comunicare tramite eventi. Non vuoi che il tuo servizio si renda conto l'uno dell'altro poiché riduce la manutenibilità. Pensa a cosa succede se devi aggiungere un nuovo servizio.
  6. Dati decentralizzati. Un servizio non dovrebbe condividere il modo in cui le informazioni sono archiviate. Proprio come un buon oggetto, espone il comportamento, non i dati.
  7. Servizio coreografico su orchestrazione.

Per raggiungere questo obiettivo, considera i limiti del servizio come capacità di business . Un processo formale di identificazione dei limiti del servizio è simile al seguente:

  1. Identifica i limiti di livello superiore. Mi piace pensare a loro come a passi che la tua organizzazione dovrebbe percorrere per raggiungere il suo obiettivo aziendale, ottenere il suo valore aziendale. Puoi farti un'idea dei passaggi di base dando un'occhiata alla catena del valore di Porter .
  2. All'interno di ciascun servizio, approfondisci. Identifica le unità autonome del bambino con le proprie responsabilità.
  3. Fai attenzione al modo in cui comunicano. I servizi corretti comunicano principalmente tramite eventi. Pensa alla tua struttura organizzativa. La comunicazione al loro interno è piuttosto intensa, anche se in genere vengono esposti alcuni eventi esterni.

Un esempio di applicare questo approccio potrebbe essere di un certo interesse.

    
risposta data 16.10.2017 - 23:28
fonte
1

Preferirei anche il secondo approccio di default, anche se forse non nel tuo "gateway API", ma considererei del tutto ragionevole creare un nuovo nuovo micro-servizio il cui unico scopo era per orchestrare le richieste ad altri micro-servizi e rappresentare i dati in una forma di livello superiore. In un'architettura di micro-servizi, mi piacerebbe che i micro-servizi "di base" comunichino direttamente tra loro.

Per renderlo un po 'meno soggettivo, diciamo che un servizio dipende da un altro se il primo richiede dati o servizi dal secondo, direttamente o indirettamente . In termini matematici, vogliamo che questa relazione sia un ordine parziale e non un preordine . In forma di diagramma, se hai tracciato il diagramma delle dipendenze dovresti ottenere un diagramma di Hasse e non avere alcun ciclo (diretto). (In un diagramma di Hasse, i bordi sono diretti implicitamente da più bassi a più alti.) Come ulteriore linea guida, si desidera che i percorsi dall'alto verso il basso siano generalmente più brevi. Ciò significa che vuoi dipendere più direttamente dalle cose per impostazione predefinita. Le ragioni sono che minimizza il numero di cose che possono andare storte per una particolare richiesta, minimizza i costi generali e riduce la complessità. Quindi, nel caso "ideale" di questa metrica, il diagramma di Hasse avrebbe solo due livelli. Naturalmente, ci sono molte ragioni per cui potresti voler introdurre servizi intermedi come la memorizzazione nella cache, il consolidamento, il bilanciamento del carico, la gestione degli errori.

Per approfondire la tua seconda preoccupazione di avere il gateway API "intelligente", un modello che sta guadagnando la trazione ora con framework come Falcor e Relay / GraphQL è per rendere le richieste più specifiche su cosa fare in modo che il "gateway API" possa genericamente eseguire tali specifiche senza dover sapere cosa comporta GetTimeline . Invece, otterrebbe una richiesta del tipo "Richiedi queste informazioni utente dal servizio utente, e ricevi questi post dal servizio postale" o qualsiasi altra cosa.

    
risposta data 17.10.2016 - 01:33
fonte
0

Ho il sospetto che il tuo bisogno di servizi di "chiamarti" significhi che stai procedendo con un sistema che non è stato ben architettato, poiché questa necessità di microservizi di "chiamarsi" è una forma di accoppiamento che appare raramente quando i microservizi sono progettati in modo appropriato.

Sei in grado di spiegare di più sul problema che stai cercando di risolvere? In inglese semplice?

    
risposta data 01.05.2018 - 17:36
fonte

Leggi altre domande sui tag