Thread di sfondo in applicazione scalata orizzontalmente

3

Ho una situazione abbastanza comune in questi giorni: ho una webapp che scala orizzontalmente su più macchine per servire un carico maggiore. Questa particolare applicazione è scritta in Java.

Su questa stessa webapp, trovo che ho bisogno di eseguire periodicamente un processo in background in questa webapp. Tuttavia, questo processo esegue richieste contro un altro servizio, e non credo che sarebbe sicuro avere più invocazioni di questo processo andando subito.

Sarebbe più semplice ottenere una nuova macchina che esegua questi processi in background da sola. Tuttavia, le politiche aziendali rendono difficile ottenere nuove macchine, quindi sto cercando di indagare su altre opzioni nel caso in cui ciò non fosse possibile. Ciò significa che sto cercando di capire come fare una sola macchina alla volta per eseguire questo processo in background contemporaneamente. Ho pensato ad alcuni dei seguenti modi:

  • Scopri come rendere una macchina "leader" ed essere l'unica ad eseguire queste attività periodiche di background. Ciò è complicato dal fatto che sto correndo su un gruppo auto-scala AWS, quindi questo leader potrebbe essere ucciso in qualsiasi momento, quindi sono bloccato a dover fare elezioni da solo.
  • Stabilire un mutex di qualche tipo che ogni istanza deve afferrare prima che venga eseguito. Ho pensato di utilizzare una griglia di dati in-memory come Hazelcast per questo, ma mi sembra un po 'pesante da configurare e utilizzare proprio per questo.

Quali sono alcuni buoni modi per raggiungere il mio obiettivo di eseguire questo processo in background nella mia webapp e assicurarmi che venga eseguito solo una volta?

    
posta dsw88 23.11.2015 - 18:53
fonte

4 risposte

3

Puoi aggiungere un altro software alla tua architettura? Se è così, ti consiglierei di usare una sorta di coda, diciamo RabbitMQ, per quella materia.

In questo scenario, non dovrai preoccuparti di gestire quale processo è in esecuzione in un dato momento (o verrà eseguito successivamente). Stanno lì in attesa di una richiesta di lavoro per arrivare via fila. Uno di loro "prenderà l'ordine" per avviare la richiesta al servizio esterno. Lo vedo come un'implementazione fuori dalla scatola per la tua idea di un "mutex".

Quello che devi capire è come accodare questo trigger "ora abbiamo bisogno di una nuova richiesta per un servizio esterno".

    
risposta data 23.11.2015 - 19:24
fonte
1

Se la tua webapp distribuita utilizza un database condiviso, puoi implementare il tuo mutext suggerito usando una riga della tabella del database e il blocco.

Tuttavia, ritengo che la soluzione migliore e più efficace sarebbe quella di utilizzare una macchina e un servizio dedicati che eseguono questo processo in background sulla propria macchina dedicata. Se il problema è il costo, è possibile ridurre al minimo il costo semplicemente facendo in modo che la macchina sia avviata e funzionante periodicamente al momento della richiesta.

    
risposta data 23.11.2015 - 19:40
fonte
1

Sembra che tu abbia bisogno di un programmatore. Questi in genere consentono l'avvio periodico dei lavori e consentono inoltre alla configurazione di assicurarsi che il lavoro venga avviato una sola volta. Utilizziamo il programma di pianificazione del quarzo , ma ci sono molte altre opzioni. Inoltre, se si esegue su un server applicazioni JEE recente, questi potrebbero fornire questa funzionalità in modo nativo, vedere JSR 352 per la descrizione dello standard JEE 7. Questo potrebbe anche fornire la funzionalità richiesta.

    
risposta data 24.11.2015 - 10:40
fonte
0

Esistono più soluzioni / tecnologie possibili:

  • Se hai un database condiviso, usalo per creare un mutex
  • Puoi utilizzare JGroups , che è una libreria leggera di comunicazione / coordinamento. Può essere facilmente integrato e ha primitive per il blocco distribuito.
  • Puoi utilizzare Zookeeper . Che è un "database" gerarchico distribuito, ma ACID / transazionale. Il blocco è supportato. Può essere incorporato (sort-of), ma richiede filesystem per memorizzare il suo database.

Soluzioni più complicate / coinvolte / pesanti:

  • Full messaging, come RabbitMQ, Kafka, ecc. (Kafka include in realtà un Zookeeper, quindi non ha senso se non hai bisogno di messaggi comunque)
  • Pianificazione nativa del contenitore JEE. Questo è complicato e personalmente ho avuto infiniti problemi con questo, specialmente in ambienti distribuiti. Ciò richiederebbe comunque un database condiviso per le implementazioni che conosco.

Questo è solo in cima alla mia testa, probabilmente ci sono molte più opzioni ...

    
risposta data 19.10.2018 - 17:31
fonte

Leggi altre domande sui tag