Evitare il polling con i componenti

3

Una volta creati componenti separati che devono comunicare tra loro, si entra nel regno della programmazione dei sistemi in cui si deve presumere che gli errori possano originarsi in qualsiasi fase del processo. Butta try-catch a bloccare la finestra e devi sviluppare solide alternative per la gestione degli errori.

Abbiamo due sistemi entrambi con apis REST. Entrambi i sistemi dispongono di GUI che gli utenti possono utilizzare per aggiungere / aggiornare informazioni. Quando le informazioni vengono aggiunte a un sistema, devono essere propagate all'altro. Abbiamo un software di integrazione (l'intermediario) che esegue il polling su base minuto per minuto, preleva aggiunte / modifiche e le traduce da un sistema all'altro. Ogni chiamata tiene traccia del timestamp dell'ultima esecuzione riuscita - abbiamo un timestamp per la comunicazione in entrambe le direzioni. In questo modo, se qualche parte del sistema fallisce, possiamo riprendere da dove eravamo rimasti quando i problemi sono stati corretti.

Ho sentito cose negative sugli approcci basati su sondaggi: vale a dire il fatto che funziona senza considerare se ci sia effettivamente lavoro. Ho sentito che gli approcci basati su push sono più efficienti perché sono attivati su richiesta.

Sto cercando di capire come avrebbe potuto funzionare un approccio basato su push. Se uno dei due sistemi tenta di spingere un add / edit, dobbiamo supporre che potrebbe fallire perché l'altro sistema è inattivo. Mi sembra che entrambi i sistemi debbano mantenere la propria coda in uscita per poter riprendere una volta risolto il problema con l'altro sistema.

Mi sembra che l'utilizzo di un approccio push elimina l'intermediario, ma accumula più responsabilità su ciascun sistema per gestire i suoi messaggi verso l'altro sistema. Questo sembra non essere un modo pulito per separare le preoccupazioni. Ora entrambi i sistemi devono assumersi le responsabilità degli intermediari.

Non vedo come ridisegnare l'intermediario per un'architettura basata su push. Corri il rischio che i messaggi vengano persi se l'intermediario stesso fallisce.

Esiste un'architettura fault-tolerant che potrebbe essere utilizzata per gestire le interazioni di sistema senza il polling? Sto cercando di capire se ci siamo persi un'alternativa migliore quando abbiamo ideato / implementato il nostro intermediario basato sul sondaggio. Il software fa il lavoro, ma c'è un po 'di latenza.

    
posta Mario T. Lanza 01.08.2014 - 14:42
fonte

3 risposte

1

Dalla tua domanda e dai commenti ad altre risposte già date, mi sembra che tu stia lavorando su due cose: 1) eliminare l'intermediario, 2) convertire il tuo meccanismo di sondaggio in un meccanismo di spinta. Direi che possono essere visualizzati separatamente. Iniziamo con la modifica da poll a push.

In generale, direi di sì, spingere è superiore al polling. Se comprendo correttamente la tua infrastruttura, hai un intermediario che esegue sondaggi in entrambe le direzioni alla ricerca di elementi da sincronizzare tra i sistemi coinvolti. Immagino che ci sia già una sorta di coda in atto. Se il tuo intermediario ha interrogato alcuni eventi di A e B è inattivo, manterrà quegli eventi finché B non sarà di nuovo in stato di ri-trasmissione. Non sono sicuro se ho capito bene, ma assumendo questo, passare a meccanismi di spinta sarebbe piuttosto semplice e il vantaggio chiaro: invece delle informazioni di recupero intermedio (che possono o non possono esserci), A (e B, ovviamente) potrebbero basta spingere i loro eventi nel mediatore. Utilizzerà le sue code esistenti e invierà push a B immediatamente o quando lo riterrà opportuno. Ora, se questo è meglio per la tua situazione dipende da un sacco di cose, principalmente la quantità di eventi previsti e il massimo ritardo consentito tra le sincronizzazioni. Attualmente, qualsiasi numero di eventi verrà sincronizzato con un ritardo di max. 1 minuto. Con la spinta, il ritardo può diminuire pesantemente ma d'altra parte, il carico può aumentare se molti eventi (che precedentemente sono stati gestiti in un gruppo) ora provocano molte spinte singolari. Tutto questo può e deve essere gestito dall'intermediario.

Se ora cerchi di eliminare l'intermediario, tutta quella coda deve risiedere all'interno dei sistemi A e B. Se ciò è fattibile dipende molto da cosa fanno attualmente A e B. Potrebbe essere oltrepassato le loro responsabilità. Inoltre, il sovraccarico di sincronizzazione attualmente molto costante potrebbe variare come descritto in precedenza. L'intermediario può anche essere buono per la riduzione del carico. I suoi meccanismi per inoltrare eventi in arrivo potrebbero essere impostati per trasmetterli in lotti. Quello che poi guadagni è: i sistemi A e B che possono avere eventi, spingerli fuori e dimenticarsene immediatamente. È bello e semplice per loro. L'intermediario potrebbe quindi, in base a varie impostazioni come il massimo ritardo, il numero massimo di eventi, ecc., Sincronizzare tali eventi nel rispettivo altro sistema.

Sono sicuro che vedi quello che sto ottenendo e potrebbe benissimo non essere quello che stai cercando. Ma forse aiuta se ci pensi in questo modo. Fammi sapere se posso chiarire le cose.

    
risposta data 02.08.2014 - 12:26
fonte
0

Se l'intermediario sta attualmente tracciando i dati in base al tempo della precedente esecuzione riuscita, quindi, per eliminare l'intermediario, ogni singolo sistema potrebbe fare lo stesso in un'architettura push. Sì, ogni sistema dovrebbe tenere traccia di questo, ma è solo un singolo timestamp, non una coda piena di messaggi.

    
risposta data 01.08.2014 - 15:05
fonte
0

It would seem to me that either system would need to maintain its own outgoing queue in order to resume once the issue with the other system is corrected.

Sì, l'accodamento è una buona soluzione per uno scenario del genere. Questo è il motivo per cui sono fatte le code: la messa in coda dei messaggi per i suoi consumatori. Ma non capisco, perché un sistema deve mantenere its own outgoing queue .

Una semplice impostazione sarebbe, che tu abbia due servizi A e B , entrambi in Incoming Messages queue. Queste code si comportano come caselle di posta . A invia messaggi a Posta in arrivo di B e viceversa. Le code fanno, quello che potrebbero fare meglio: mettere in coda quei messaggi.

Le condizioni in cui i messaggi arrivano al consument di tale coda sono a) all'avvio, il servizio si registra come consumatore e ottiene le informazioni, che ci sono messaggi nella "casella di posta", quindi il servizio li fa apparire uno alla volta fino a quando la "casella di posta" è vuota e b) ogni volta che arriva un nuovo messaggio, il servizio riceve una notifica e apre messaggi non letti finché la casella di posta è vuota.

Dissocia i tuoi sistemi con due code di messaggi. Invii messaggi in un fire-and-forget -manner. La domanda se il destinatario è vivo non disturba il mittente. Una coda farebbe ciò che fa il tuo attuale middleware , ma in un modo più semplice.

Il punto di errore si sposta dal destinatario diretto, ad es. servizio A , all'infrastruttura di accodamento, che deve essere resiliente / ridondante = tollerante agli errori .

Each invokation keeps track of the timestamp of the last successful run--we have one timestamp for communication in either direction. In this way, if any part of the system fails, we can resume right where we left off when the issues are corrected.

Le code nello scenario precedente stavano agendo come pile e avrebbero conservato l'ordine.

E dal momento che si tratta di un sistema distribuito, devi gestire CAP ; parlato semplicemente: il problema, che hai due servizi di sincronizzazione, che potrebbero essere interrogati simultaneamente.

    
risposta data 01.08.2014 - 16:17
fonte