Progettazione dell'architettura basata su eventi per più servizi

5

Ho creato circa una dozzina di servizi per una intranet. Ora sono arrivato al punto che questi servizi sono più accoppiati tra loro rispetto a quelli con cui mi trovo a mio agio, e ho riscontrato problemi in cui una volta che il servizio può causare la degradazione di alcuni altri servizi.

Ho lavorato su un progetto EDA in modo da poter rendere questi servizi disaccoppiati l'uno dall'altro, ma poiché sono l'unico programmatore qui ho bisogno di un feedback.

Il design mira a risolvere questi scenari:

Scenario 1: il client richiede i dati dal servizio A, per soddisfare la richiesta Il servizio A richiede i dati dal servizio B ma il servizio B non funziona e non risponde

Scenario 2: il client aggiorna un'entità nel servizio B, il riferimento a questa entità deve essere aggiornato nei servizi A e C

Ho diviso il design in due parti, Operazioni e Eventi

Un'operazione viene inviata da un servizio o un client per modificare un'entità in un servizio. Ciò si traduce sempre in un evento che viene licenziato. Ogni operazione contiene un ID utente, un ID operazione e alcuni timestamp.

Un evento è una reazione a un'operazione, notifica a chiunque stia ascoltando che si è verificata una modifica. Ogni evento contiene l'id dell'operazione che l'ha avviato, l'id dell'utente che l'ha causato e alcuni timestamp. Ogni evento ha anche un hash dell'entità completa in modo che tutti gli ascoltatori possano confrontarsi con le loro versioni.

Uso RabbitMQ come bus dei messaggi e ogni servizio ha code permanenti e permanenti per archiviare eventi o operazioni in sospeso.

Per disaccoppiare il servizio gli uni dagli altri, ogni servizio memorizza nella cache qualsiasi entità che dipende da quella che appartiene a un altro servizio.

Quando un servizio richiede un'entità da un altro servizio lo recupera e lo memorizza in una tabella nel suo database. Quindi ascolta le modifiche apportate a qualsiasi entità nella sua cache e le aggiorna quando si verifica un evento correlato ad esso.

Quando la memorizzazione o il recupero di un'entità dalla cache non riesce, lo recupera nuovamente dal servizio appropriato.

Per l'auditing, ho un servizio che ascolta gli eventi da tutti i servizi e li memorizza. Può quindi ricreare qualsiasi entità in qualsiasi momento specifico.

Mi piacerebbe ricevere commenti da chiunque sia più esperto di me e se ci siano problemi evidenti con il design.

    
posta grimurd 16.02.2018 - 17:23
fonte

2 risposte

2

Ho ricevuto un paio di cose che vorrei sottolineare:

  1. Mi riferisco ai comandi invece di operazioni . Penso che il gergo attorno al sistema che stai modellando meglio.
  2. Sembra che tu stia utilizzando gli eventi come trigger per recuperare i dati da altri servizi. Utilizzerai anche gli eventi per creare quelle entità in primo luogo? In questo caso, suggerirei vivamente di introdurre qualche forma di EventStore per ogni applicazione per archiviare gli eventi in cui si sta pubblicando. Puoi quindi riutilizzare quegli eventi per ricreare le tue entità se necessario. La maggior parte delle persone si riferisce a questo come Event Sourcing, anche se preferisco usare quel termine per il lato di scrittura (la 'gestione delle operazioni' nel tuo esempio) dell'applicazione. Nondimeno, creerei le tue entità anche su quegli eventi. Se si adottasse questo approccio, si potrebbe anche consentire agli altri servizi di ascoltare tutti quegli eventi e creare l'entità di cui avrebbero bisogno essi stessi, il che ometterà la necessità di interrogare le entità.
  3. Sottolinea che aggiungerai un altro servizio per il controllo. Se segui il mio suggerimento dal punto 2, il tuo archivio eventi sarà automaticamente anche il registro di controllo. Questo ovviamente vale solo se modellate correttamente i vostri eventi, ma comunque ritengo che rendere i vostri eventi cittadini di prima classe e archiviarli immediatamente dopo la pubblicazione ometta la necessità di un servizio di audit-log dedicato.
  4. Senza sapere in che linguaggio di programmazione ci si trova, suggerirei comunque di dare un'occhiata ad alcuni framework CQRS / EDA / DDD, come il Axon Framework per esempio. È basato su Java, ma anche se non sei su Java, i concetti che il framework cerca di aiutarti assomigliano a ciò che stai cercando di fare.

Da capo, penso che il rimodellamento della tua applicazione su qualcosa come il tuo suggerimento sia una buona cosa. Rendendo trasparenti i tuoi messaggi di comunicazione e la tua posizione dei servizi, assicurati di perdere l'accoppiamento di cui sei preoccupato in questo momento.

    
risposta data 19.02.2018 - 17:06
fonte
2

Prima di tutto, se il servizio A ha bisogno di dati dal servizio B, allora i confini del servizio sono sbagliati. Sembra che i criteri che hai usato per suddividere il tuo sistema siano per entità. Correlato al concetto di servizi a strati, che era già considerato malvagio nel 2007 .

L'approccio che sto sostenendo è basato sul concetto di capacità aziendale. Identifica alcune aree del tuo dominio che sono davvero molto coese, che comprendono alcuni dati incapsulati utilizzati solo all'interno di quell'area, i processi di business implementati lì, le applicazioni e le persone. Quindi approfondisci queste aree e ripeti quel passaggio. Trovo comodo utilizzare una analisi della catena del valore per questo. Considera il tuo primo processo aziendale. Come guadagni, qual è la ragione principale dell'esistenza del tuo business? Dai un'occhiata a questo processo come una sequenza di passaggi. Se qualche passaggio contiene alcuni processi di business che non sono connessi con altri passaggi, probabilmente questi passaggi possono essere un servizio autonomo.

I tuoi servizi tecnici sono associati a tali servizi aziendali come 1: 1.

C'è una serie di post su SOA che contengono anche alcuni esempi , dai un'occhiata.

    
risposta data 20.02.2018 - 19:15
fonte