2011-10-16 10 views
10

Una delle grandi cose del framework Play è che è completamente stateless e solo orientato alla richiesta/alla risposta. Questo è davvero bello poiché mi consente di distribuire la mia app sul cloud e di ridimensionare il numero di istanze dietro il mio bilanciamento del carico senza dovermi preoccupare della replica di stato (sessione) ...Quadro di gioco: impatto dei lavori sul modello stateless

Recentemente, tuttavia, avevo bisogno di eseguire alcune logiche di applicazione al di fuori di una richiesta HTTP e scoprire che Play ha la possibilità di definire lavori che sono completamente gestiti dal framework. Sembra brillante ma solleva la domanda: come si inseriscono questi lavori nel modello stateless utilizzato da Play?

Dire che ho un'attività di manutenzione che deve essere eseguita ogni ora e definisco un lavoro pianificato per quello. Se quindi distribuisco più istanze di riproduzione dietro un servizio di bilanciamento del carico, tale lavoro verrà avviato contemporaneamente su ciascuna istanza? E se sì, quale sarebbe un buon approccio per gestire i lavori che devono essere eseguiti "esclusivamente"?

Stavo pensando di creare una nuova istanza di riproduzione su un server non in cluster, riutilizzando il modello JPA dell'istanza esistente (in cluster) (e quindi connettendola allo stesso database). Questa nuova istanza conterrà solo i lavori di manutenzione e poiché è ospitata su un server non in cluster, non vi è alcun rischio che un lavoro sia in esecuzione contemporaneamente. Allo stesso tempo, questo mi permetterebbe di mantenere la mia istanza cluster esistente completamente apolidi e facile da ospitare/bilanciare il carico. Questo sarebbe un buon approccio?

+0

Iniziare una taglia, vedere sotto. – ripper234

risposta

5

Suggerirei di raggruppare il lavoro anche. È possibile impostare un semaforo nel database per garantire che sia in esecuzione un solo lavoro. Un'altra idea è dare un'occhiata all'Akka-Framework, che sarà incluso in Play 2.0. Penso che abbia costruito un meccanismo con la gestione di questo problema, ma non ne sono sicuro. Non ho esperienze con Akka.

5

Dato che i nomi di una bandiera nel DB sono menzionati, è utile sapere se il lavoro è già in esecuzione. Io uso un semaforo db con altre bandiere per darmi lo stato del lavoro e informazioni extra.

Un'altra cosa che si potrebbe fare è utilizzare Play.id per calcolare quale istanza deve essere in esecuzione i lavori. Usiamo "giocare dall'inizio -% prod", "inizio riproduzione -% prod1" ... per avviare le applicazioni e di seguito nel mio doJob() metodo:


doJob(){ 
    if ("prod".equalsIgnoreCase(Play.id)) { 
    ... 
    } 
} 
+0

Grazie!Non mi piace l'idea di bloccare il mio DB per questo, ma mi piace il tuo suggerimento di verificare su quale istanza è in esecuzione il lavoro! – stikkos

2

Avendo ottenuto un rapido sguardo in il codice sorgente di Play Framework (classi Job e JobsPlugin) penso che non siano adatti per l'uso in un ambiente cluster quando è importante che il processo venga eseguito solo una volta per un intervallo di tempo (senza introduzione di brutti hack).

Vedo tre possibili soluzioni:

  1. utilizzare un job scheduler che supporta il clustering. La scelta più ovvia è Quartz. La riproduzione utilizza anche parti di Quartz (per analizzare le espressioni CRON), ma non la parte che esegue la pianificazione.

  2. Quando si utilizza la riproduzione 2, è possibile andare su Akka, che offre a scheduler.

  3. Cambia il tuo lavoro in modo che non importi quando viene eseguito due volte (possibile per alcuni casi d'uso).

+0

Sì, stiamo attualmente pensando alla soluzione n – ripper234