Quale approccio dovrei usare per dividere un'applicazione monolitica in diversi microservizi?

3

Abbiamo un enorme progetto che ha disperatamente bisogno di essere suddiviso in più database e applicazioni. Posso pensare a 2 possibili approcci a questo problema:

  1. Utilizzare un endpoint REST su ciascun servizio per recuperare / aggiornare i dati. I servizi che dipendono l'uno dall'altro si richiamano reciprocamente gli endpoint REST a vicenda per recuperare / aggiornare i dati. (questo ha più senso per me, e sembra avere una buona separazione delle preoccupazioni in termini di quali dati ogni servizio dovrebbe "possedere")
  2. Utilizza le code per passare i messaggi "entità aggiornate" tra i servizi e replica i dati che sono stati aggiornati tra tutti i servizi che necessitano dei dati.

Il mio vantaggio, in realtà, vuole davvero andare con la seconda opzione perché pensa che sarà più conveniente e resiliente: utilizzando questo approccio, non abbiamo bisogno di scalare tutti i servizi dipendenti di un particolare microservizio perché i dati sono replicato, e possiamo anche recuperare i dati necessari anche se un microservizio dipendente è inattivo (di nuovo perché i dati sono replicati). Questo tipo di cosa ha senso per me, tuttavia, il mio istinto mi sta dicendo che questa è una cattiva idea perché i bug di replica mi rendono nervoso, e sembra complicato da implementare correttamente (molti modi possibili i dati potrebbero andare fuori sincrono, e doesn ' Sembrare banale risincronizzare manualmente tutti i dati che è necessario utilizzare in più servizi). Non ho mai lavorato con un'architettura simile a quella menzionata al punto # 2, quindi potrei essere completamente fuori base qui, motivo per cui sto postando qui e chiedendo consigli. Cosa consigliereste tutti? # 1 o 2? Qualcos'altro interamente? Grazie in anticipo!

    
posta Ben 14.09.2016 - 09:56
fonte

1 risposta

4

L'approccio preferito dipenderà da diversi fattori. Nella mia azienda, utilizziamo entrambi gli approcci (utilizzando Hermes piuttosto che una coda per la comunicazione asincrona) poiché entrambi hanno i loro vantaggi in determinate situazioni .

Il principale fattore di interesse è quali requisiti hai sulla freschezza dei dati per una determinata coppia di servizi. Fondamentalmente, la comunicazione asincrona (come l'uso di una coda) ha il vantaggio di causare un minore accoppiamento tra i servizi e potenzialmente un throughput migliore poiché è possibile pianificare il trasferimento dei dati in un momento opportuno, ripetere le trasmissioni fallite tutte le volte che si desidera e così via. Il rovescio della medaglia è che le cose accadono in modo asincrono, quindi c'è sempre un po 'di ritardo in quanto un servizio vede dati obsoleti prima che ottenga un aggiornamento dall'altro. Potrebbero inoltre essere necessarie notevoli risorse di disco e CPU se si desidera duplicare un database di grandi dimensioni in ciascun servizio.

Inoltre, considera che in un sistema distribuito, le cose semplici come "fare una copia di dati in un altro posto" diventano complicate. Se si dispone di un'istanza dell'applicazione A e di un'istanza dell'applicazione B e tutto avviene in modo sincrono, è possibile creare e mantenere sincronizzata una copia autentica di tutti i dati dal servizio A al servizio B. Ma quando si hanno N istanze di A che comunicano con M istanze di B, e per peggiorare le cose, la comunicazione è asincrona, è davvero difficile mantenere una copia aggiornata. Ad esempio, l'istanza A1 può aggiornare un documento, quindi l'istanza A2 aggiorna anche lo stesso documento e ora hai due eventi di aggiornamento da corsa per raggiungere le istanze B1 e B2 che possono ricevere e applicarli in qualsiasi ordine. È un grande argomento, ma il take-out è la complessità che cresce molto.

Quindi, ecco alcuni esempi concreti di quando utilizzare ciascuno degli approcci potrebbe essere la scelta migliore:

  • Hai un servizio di autorizzazione con informazioni sugli utenti e i loro diritti di accesso. Qui, il REST è preferito: vuoi che qualsiasi cambiamento (come la rimozione delle autorizzazioni di un utente) sia attivo immediatamente. Per motivi di sicurezza, inoltre, non desideri effettuare alcuna copia delle informazioni personali o delle credenziali degli utenti.
  • Un servizio mostra pubblicità per determinati prodotti che il tuo negozio web sta vendendo. L'annuncio di ogni prodotto contiene un nome, una breve descrizione e un URL di collegamento. Supponendo che il numero di prodotti pubblicizzati non sia enorme, è preferibile fare una copia tramite comunicazione asincrona. I prodotti non vengono aggiornati molto spesso e se lo sono, è possibile aggiungere un ritardo di alcuni minuti prima che la modifica sia visibile negli annunci. Il tuo ad server può indicizzare gli annunci in un formato speciale ottimizzato per il rendimento della pubblicazione di annunci e i servizi sono strettamente associati: il tuo servizio di annunci non aumenta il carico sul database del prodotto principale come se stesse utilizzando le richieste REST.
  • Le pagine di elenco del tuo negozio mostrano i prodotti che vendi. Qui, probabilmente vorrai richiedere il servizio del database del prodotto direttamente tramite REST. Quando modifichi un prodotto, vuoi che la modifica sia visibile nella pagina del tuo negozio il prima possibile. L'intero database del prodotto è probabilmente abbastanza grande, quindi duplicarlo nel servizio di frontend sarebbe un grande costo dell'hardware.

Come vedi, ci sono buoni casi d'uso per entrambi gli approcci, e in un sistema di grandi dimensioni probabilmente dovrai accontentarti di usare un approccio ibrido per usare # 1 o # 2 a seconda della situazione.

    
risposta data 14.09.2016 - 16:56
fonte

Leggi altre domande sui tag