Backstory
Possiedo un'applicazione del server di messaggistica responsabile dell'intermediazione / proxy delle chiamate effettuate da un livello applicazione a numerosi servizi esterni. Lo scopo di questa applicazione è di astrarre gli aspetti tecnici del richiamo di questi servizi lontano dal livello di applicazione principale.
Funziona bene poiché l'Application Server non deve preoccuparsi dei protocolli http / ldap ecc, wcf, ftp, soap, ebxml, ecc. Semplicemente inviano un "payload", con pochi identificatori, e il server Messaging gestisce il riposo. Significa anche che se una definizione del servizio cambia, il server delle applicazioni non deve essere modificato. Inoltre, il server di messaggistica viene chiuso da un database SQL 2008 che archivia una verifica di tutti i messaggi inviati e le risposte associate, ecc.
L'architettura generale del flusso di dati di questo è la seguente:
Application Server (s) = > Load Balancer = > Server di messaggistica = > [X] = > Servizi esterni
La domanda
Devo implementare un meccanismo di tentativi nel livello dell'applicazione di messaggistica. L'intenzione è di ripristinare con garbo le situazioni in cui il server di messaggistica non è in grado di inoltrare il servizio di destinazione (ovvero servizio inattivo, problemi di rete, timeout, ecc.), I problemi con il punto [X] nell'architettura sopra.
Il requisito di progettazione di alto livello è:
Application Server invia una richiesta al server di messaggistica. Questo quindi tenta di inoltrare ai servizi esterni. Se il primo tentativo non riesce, il server di messaggistica risponde in modo sincrono all'application server affermando che il messaggio è "in riprova"
Il server di messaggistica procede quindi a riprovare l'intemperie per il contratto (ad esempio, X tentativi con Y secondi tra ciascuno).
Una delle due cose succederà dopo, tutti i tentativi contrattuali saranno stati eseguiti senza successo o uno dei tentativi avrà esito positivo. In entrambi i casi, un messaggio viene inviato di nuovo nel livello applicazione per notificare lo stato della richiesta di messaggistica.
Alcuni gothcas
Il messaggio da riprovare non può essere trattenuto nella "memoria" come se il server di messaggistica non fosse attivo. Inoltre, un contratto di ripetizione può essere 5 volte una volta ogni 12 ore, non è possibile tenere i dati in memoria per quel periodo di tempo. Ciò detto, alcuni contratti di ripetizione potrebbero essere 5 volte una volta ogni 5 secondi.
Se la rete di inoltro si interrompe e quindi recupera il carico dei tentativi, deve essere distribuito su tutto il livello di messaggistica anziché su un singolo server.
La domanda
La comunicazione tra il livello di applicazione e di messaggistica non è una preoccupazione poiché tale struttura è già in atto. Tuttavia, l'architettura del retry framework nel livello di messaggistica è ancora nell'aria. Come implementeresti questo?
Opzioni che abbiamo / stiamo considerando
In caso di errore, memorizza i dati di prova in un database, quindi disponi di un servizio di polling che controlla il database ogni secondo. Se viene trovato un messaggio pianificato per il tentativo, questo viene reindirizzato al livello di messaggistica tramite Load Balancer
In caso di errore archiviare i dati di tentativi in un database, utilizzare un lavoro CLR per eseguire il polling del database e inviare i messaggi, pianificati per riprovare, nuovamente su Load Balancer
Altre informazioni
Può o potrebbe non essere pertinente:
- Tutto il codice è C #
- I database sono SQL 2008
- Le comunicazioni da livello Application a Messaging vengono eseguite tramite WCF con BasicHttpBinding.
- Abbiamo il controllo completo su tutti gli aspetti del livello del server di messaggistica e nessun controllo sul livello applicazione.
- Il livello di messaggistica attualmente gestisce circa 500k transazioni all'ora, quindi puoi immaginare quanto velocemente le cose verranno sottoposte a backup in caso di errore su uno dei servizi esterni