Domanda

So che con Network Load Balancing e Failover Clusteringwe posso fare servizi passivi ad alta disponibilità. Ma che dire di apps attivi

Esempio: una delle mie applicazioni recupera alcuni contenuti da una risorsa esterna in un intervallo fisso. Ho immaginato i seguenti scenari:

  1. Esegui in una singola macchina. Problema: se questa istanza cade, il contenuto non sarà recuperato
  2. Esegui in ogni macchina del cluster. Problema: il contenuto verrà recuperato più volte
  3. avere in ogni macchina del cluster, ma farlo funzionare solo in uno di essi. Ogni istanza dovrà verificare una sorta di risorsa comune per decidere se il suo turno per fare il compito o no.

Quando stavo pensando la soluzione # 3 mi sono chiesto che cosa dovrebbe essere la risorsa comune. Ho pensato di creare una tabella nel database, dove abbiamo potuto utilizzare per ottenere un blocco globale.

E 'questa la soluzione migliore? Come fa la gente di solito fanno questo?

Tra l'altro si tratta di un C # .NET WCF applicazione in esecuzione su Windows Server 2008

È stato utile?

Soluzione

Per tali problemi hanno inventato code di messaggi. Immaginate il caso in cui le applicazioni cluster tutti ascoltano una coda di messaggi (per sé cluster :-)). Ad un certo punto nel tempo un caso ottiene il vostro ordine iniziale per scaricare la vostra risorsa esterna. In caso di successo, l'istanza svuota il messaggio e invece i messaggi un altro per un tempo di esecuzione più tardi che di uguale a 'il tempo di esecuzione' + 'intervallo'. Ma nel caso degli stampi esempio durante la lavorazione, che non è un problema. Il messaggio è rotolato indietro nella coda (dopo il timeout) e qualche altra istanza può raccoglierlo. Un po 'di transazioni, un po' di code di messaggi

Sono sul lato Java EE del mondo in modo può aiutare con la codifica dettagli

Altri suggerimenti

Ho una volta implementato qualcosa di simile utilizzando la soluzione # 3.

Creare una tabella denominata qualcosa come resource_lock, con una colonna (ad esempio locking_key) che conterrà una chiave di bloccaggio.

Poi ad ogni intervallo, tutte le istanze della vostra applicazione sarà:

  1. Esegui una query come 'update resource_lock set resource_key = 1 where resource_key is null'. (Potete naturalmente anche inserto un server specifico ID, un timestamp, ecc.)
  2. Se 0 righe aggiornate:. Non fanno nulla - un'altra istanza app è già il recupero della risorsa
  3. Se 1 riga aggiornata: prendere la risorsa e insieme locking_key torna a null.

Ci sono due vantaggi con questo:

  • Se uno dei server fallisce, la risorsa sarà ancora recuperati dai server che sono ancora in corso.
  • Si parte il blocco alla base di dati, questo consente di risparmiare da attuare da soli.

Ci sono alcuni requisiti che, probabilmente, si sa, ma non sono stati descritti nella domanda che fanno dare una risposta informata sfida. Alcune di queste domande sono:

  • Ha il compito portare a termine con successo?
  • Se l'operazione non / non viene completata con successo "che" ha bisogno di sapere e che tipo di azioni devono essere eseguite?
  • Qual è il comportamento se il compito non è stato completato, quando arriva il momento di eseguire nuovamente l'operazione? Nel caso in cui correre o no?
  • Quanto è importante che i lavori eseguiti durante l'intervallo specificato? Se l'intervallo è ogni 5 minuti ci si deve essere ogni 5 minuti o potrebbe l'esecuzione dell'attività dopo 5 minuti e 10 secondi?

Il primo passo è quello di rispondere come il task periodico viene pianificata l'esecuzione. Una possibilità è un'attività pianificata di Windows, ma che non è di per sé altamente disponibile, ma può essere possibile per il lavoro intorno a quello. Se si utilizza SQL Server, un'altra alternativa sarebbe quella di utilizzare SQL Server Agent come uno scheduler in quanto sarà failover come parte di SQL Server.

Il passo successivo per determinare è come richiamare l'applicazione WCF. L'opzione più semplice sarebbe quella di innescare un lavoro per richiamare il servizio WCF tramite un indirizzo IP NLB. Questo potrebbe essere considerato un no-no, se il server di database (o un altro server in quella zona) sta chiamando alla zona di applicazione (naturalmente ci sono sempre, come MSDTC eccezioni).

Un'altra opzione potrebbe essere l'utilizzo del modello di coda. Questo sarebbe il più affidabile nella maggior parte delle situazioni. per esempio. Agente SQL Server potrebbe eseguire una stored procedure per inserire un record in una tabella di coda. Poi su ogni server di applicazione di un servizio potrebbe polling alla ricerca di un record in coda al processo. L'accesso al record nella coda sarebbe stato serializzato dal database in modo che il primo server potrebbe eseguire il lavoro (e che lavoro sarebbe eseguito solo una volta).

A seconda delle risposte alle domande di apertura di questa risposta potrebbe essere necessario aggiungere un po 'di più la gestione degli errori. Se il recupero della risorsa esterna è di solito piuttosto breve, si consiglia di mantenere semplicemente il record di coda bloccato con una select for update e aggiornamento quando il compito è completato lo stato (o eliminare il record se lo si desidera). Questo bloccherà le altre istanze del servizio di elaborare il record mentre è in fase di elaborazione su un altro server e se si verifica un crash durante l'elaborazione della transazione dovrebbe essere il rollback e un altro servizio del cluster può prendere il record. (Anche se, si potrebbe aumentare il timeout transazione fino a quando si pensa che è necessario.)

Se tenere un blocco del database per un lungo periodo non è praticabile, allora si potrebbe cambiare la logica e aggiungere un po 'di monitoraggio per i servizi. Ora, quando un lavoro viene avviato l'elaborazione, il suo stato sarebbe cambiato dalla coda per l'esecuzione e il server che sta elaborando il record sarebbe stato aggiornato il record. Una sorta di tabella di stato del servizio potrebbe essere creato e ogni istanza del servizio sarebbe aggiornare il tempo corrente ogni volta che il polling. Ciò consentirebbe di altri servizi del cluster per i lavori ritrattano che mostrano come in esecuzione, ma il servizio che si suppone di essere in esecuzione su non si è "check-in" entro un certo periodo.

Questo approccio ha anche dei limiti: e se il compito effettivamente completato ma in qualche modo la connettività di database è stato perso - il lavoro potrebbe potenzialmente eseguire nuovamente. Naturalmente, non credo che il problema di avere azioni di database atomiche combinate con altre risorse non transazionali (ad esempio richiesta Web, file system) sta per essere facilmente risolto. Sto assumendo che si sta scrivendo un file o qualcosa -. Se il contenuto esterno è anche posto in un database allora una singola transazione garantirà che tutto sia coerente

Dal punto di vista la semplicità, l'/ modo più semplice e veloce per realizzare quello che stai cercando potrebbe essere quella di 'round robin' il cluster in modo che per ogni richiesta, viene selezionata una macchina (da un servizio di gestione dei cluster o alcuni tale) per elaborare una richiesta. le richieste dei client effettivi non vanno direttamente alla macchina che lo gestisce; essi invece indicano un singolo endpoint, che funge da proxy per distribuire le richieste in ingresso alle macchine in base alla disponibilità e del carico. Per citare sul link qui sotto-referenziata,

  

Bilanciamento carico di rete è un modo per configurare un pool di macchine in modo che, a turno, di rispondere alle richieste. E 'più comunemente visto implementato nel server farm: macchine la stessa configurazione che si diffondono il carico per un sito web, o forse una fattoria Terminal Server. Si potrebbe anche usare per un firewall (ISA) farm, punti di accesso VPN, in realtà, ogni volta che avete il traffico TCP / IP che è diventato troppo carico per una singola macchina, ma si vuole ancora che appaia come una sola macchina per scopi di accesso.

Per quanto riguarda l'applicazione essere "attivo", tale requisito non tiene conto in questa equazione dal se 'attivo' o 'passiva', l'applicazione rende ancora una richiesta ai server.

Esistono

bilanciamento del carico commerciali per servire le richieste HTTP in stile, in modo che possa valere la pena guardare in, ma con il bilanciamento del carico caratteristiche di W2k8, si può essere meglio serviti toccando in quelle.

Per ulteriori informazioni su come configurare che in Win2k8, vedere questo articolo .

questo articolo è molto più tecnico e si concentra sull'uso di NLB con Exchange, ma i principi devono ancora applicare alla vostra situazione.

Vedi qui per un altro dettagliata walk-through di installazione e configurazione NLB.

In mancanza di questo, si può essere ben servita da una ricerca / intervento sul ServerFault, dal momento che il codice dell'applicazione non è (e non dovrebbe essere) rigorosamente consapevoli del fatto che la NLB esiste anche.

EDIT:. Ha aggiunto un altro collegamento

EDIT (2 °): Il PO ha corretto la mia conclusione erronea nel concetto 'attivo' vs 'passiva'. La mia risposta è molto simile alla mia risposta originale, salvo che il servizio 'attivo' (che, dal momento che si sta utilizzando WCF, potrebbe facilmente essere un servizio di Windows) potrebbe essere diviso in due parti: la parte di elaborazione effettiva, e il porzione gestione. La parte di gestione dovrebbe funzionare su un singolo server, e agire come un bilanciamento del carico round-robin per gli altri server che fanno il trattamento effettivo. E 'un po' più complicato di scenario originale, ma credo che avrebbe fornito una buona dose di flessibilità, nonché offrire una netta separazione tra la logica di elaborazione e di gestione.

In alcuni casi le persone trovano utile avere 3 macchine che fanno tutte le richieste, e poi confrontare i risultati, alla fine, per assicurarsi che il risultato è assolutamente corretto e nessun guasto hardware causato problemi durante l'elaborazione di esso. Questo è quello che fanno avanti per esempio aeroplani.

In altri momenti, si può vivere con avere un unico risultato cattivo e un piccolo tempo morto per passare a un nuovo servizio, ma vogliono solo il prossimo a essere ok. In quel numero soluzione caso 3 con un monitor del battito cardiaco è un setup eccellente.

Altre volte ancora una volta, la gente ha solo bisogno di essere avvisato con uno SMS che il loro servizio è giù e l'applicazione sarà solo utilizzare alcuni dati obsoleti finché non si esegue manualmente una sorta di failover.

Nel tuo caso, direi che il secondo è probabilmente più utile per voi. Dal momento che non si può davvero dipendere il servizio all'altra estremità essendo disponibile, si devono ancora trovare una soluzione per che cosa fare in questo caso. Restituire dati obsoleti può essere ciò che è bene per voi, e non può essere. Mi dispiace dover dire: Dipende

.

Zookeeper fa un caso d'uso di serrature buona distribuiti. Zookeeper avere z-nodi che sono come directory con i dati.

Anche curatore Netflix ha molte ricette già fatto e da utilizzare. Come: elezione leader, blocco distribuiti e molti altri.

Credo che abbiamo cliente del guardiano dello zoo per C #. Si dovrebbe provare questa opzione. # Option3

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top