2012-01-16 9 views
12

Stiamo eseguendo un'applicazione web Spring 3.0.x (.war) con un lavoro notturno @Scheduled in un ambiente WebLogic 10.3.4 in cluster. Tuttavia, poiché l'applicazione viene distribuita su ciascun nodo (utilizzando la procedura guidata di distribuzione nella console Web dell'AdminServer), il lavoro viene avviato su ciascun nodo ogni notte, quindi viene eseguito più volte contemporaneamente.Eseguire l'attività @Scheduled solo su un nodo del cluster WebLogic?

Come possiamo evitare che ciò accada?

So che le librerie come Quartz consentono di coordinare i lavori all'interno di un ambiente cluster mediante una tabella di blocco del database o potrei persino implementare qualcosa di simile. Ma poiché questo sembra essere uno scenario abbastanza comune mi chiedo se Spring non abbia già un'opzione su come aggirare facilmente questo problema senza dover aggiungere nuove librerie al mio progetto o inserire soluzioni alternative.

  • Non siamo in grado di eseguire l'aggiornamento a Spring 3.1 con profili di configurazione, as mentioned here

Per favore fatemi sapere se ci sono questioni aperte. Ho anche fatto questa domanda sul Spring Community forums. Grazie mille per il vostro aiuto.

+0

Vuoi ottenere un qualche tipo di failover? Se così i profili di configurazione non saranno davvero utili qui e avrai comunque bisogno di sincronizzazione. Avevamo un requisito simile e abbiamo finito con un lock table che fornisce anche alcuni riepiloghi di esecuzione rapidi. – mrembisz

+0

@mrembisz No, al momento non stiamo cercando il failover, poiché ciò complicherebbe molto le cose. –

risposta

2

Stiamo implementando la nostra logica di sincronizzazione utilizzando una tabella di blocco condivisa all'interno del database dell'applicazione. Ciò consente a tutti i nodi del cluster di verificare se un lavoro è già in esecuzione prima di avviarlo.

+0

Che livello di isolamento stai usando qui? Leggi_committed o serializable? –

5

Abbiamo solo un'attività che invia un'email di riepilogo giornaliera. Per evitare dipendenze aggiuntive, controlliamo semplicemente se il nome host di ciascun nodo corrisponde a una proprietà di sistema configurata.

private boolean isTriggerNode() { 
    String triggerHostmame = System.getProperty("trigger.hostname");; 
    String hostName = InetAddress.getLocalHost().getHostName(); 
    return hostName.equals(triggerHostmame); 
} 

public void execute() { 
    if (isTriggerNode()) { 
     //send email 
    } 
} 
+0

Questa è una bella idea, grazie per aver condiviso! –

3

Fate attenzione, dal momento che nella soluzione di implementare la propria logica di sincronizzazione utilizzando una tabella di blocco condiviso, si ha sempre il problema di concorrenza in cui i due nodi del cluster sono la lettura/scrittura dal tavolo allo stesso tempo.

migliore è quella di effettuare le seguenti operazioni in una transazione db: - leggi il valore nella tabella di blocco condiviso - se non altro nodo sta avendo il blocco, prendere la serratura - aggiornare la tabella che indica si prende la serratura

+0

Ciao Mathias. Anche se è passato un po 'di tempo, grazie per il tuo utile suggerimento. Effettuiamo effettivamente il controllo e la scrittura della voce di blocco all'interno di una singola transazione. Buon punto e una trappola comune. –

0

È possibile provare a utilizzare TimerManager (Pianificatore processi in un ambiente cluster) da WebLogic come implementazione TaskScheduler (TimerManagerTaskScheduler). Dovrebbe funzionare in un ambiente cluster.

Andrea

3

ho risolto questo problema facendo una scatola come master. imposta fondamentalmente una variabile d'ambiente su una delle caselle come master = true.

e leggerlo nel codice java tramite system.getenv ("master"). se presente e vero, quindi esegui il tuo codice.

frammento di base

@schedule() 
void process(){ 
boolean master=Boolean.parseBoolean(system.getenv("master")); 
if(master) 
{ 
    //your logic 
} 

} 
+1

Penso che questa non sia la soluzione migliore, immaginiamo di avere un cluster di due nodi, hai fatto il primo nodo come master e il secondo NON lo è. Dopo che per qualsiasi motivo il primo nodo è andato giù, il tuo lavoro non verrà eseguito perché il nodo che dovrebbe gestire il processo verso il basso, quindi perderai la funzionalità più importante nell'ambiente cluster "Alta disponibilità" – AmjadD

0

Possiamo fare altre macchine sul cluster non eseguire il processo batch utilizzando la seguente stringa cron. Non funzionerà fino al 2099.

0 0 0 1 1?2099