6 Stimmen

Spring Framework Verbindung der JVM untereinander

Ich habe 4 Server und JVM ist auf ihnen installiert. Ich habe einen Java-Dienst geschrieben, den Quartz alle 10 Minuten aufruft. Aber bei 4 Servern werden alle 10 Minuten 4 Aufrufe gemacht. Diese Situation schafft eine Wettlaufsituation. Ich möchte nur einen Dienst auf 4 JVM.

Wie kann ich das mit Spring Framework erreichen?

3voto

skaffman Punkte 389758

Ihre Frage ist nicht ganz klar, also lassen Sie mich sehen, ob ich Sie verstehe: Sie haben 4 Server, auf denen jeweils Quartz in einer VM läuft, und jeder Server hat denselben Quarz-Job, der alle 10 Minuten ausgeführt werden soll, mithilfe eines Cron-Ausdrucks. Alle 10 Minuten starten alle 4 Server denselben Job, was zu Ihrer Race Condition führt, da sie alle versuchen, dasselbe zur gleichen Zeit zu tun.

Das ist nicht wirklich ein Job für den Frühling. Quartz verfügt jedoch über eine Clustering-Funktion, bei der Sie einen Auftrag so konfigurieren, dass er nur auf einem einzigen Server im Cluster ausgeführt wird. Es verwendet eine gemeinsame Datenbank, um zu koordinieren, welche Server welchen Auftrag ausführen, und stellt sicher, dass sie dies nicht alle gemeinsam tun.

Die Dokumente enthalten einige Informationen dazu aquí aber im üblichen opensymphony.com-Stil sind sie ziemlich spärlich und wenig hilfreich.

0 Stimmen

Mit Ihrer Erklärung habe ich die Frage verstanden, skaffman. Großartig. +1 dafür.

3voto

Chris Dail Punkte 24971

Dies ist mit Quartz eigentlich recht einfach zu bewerkstelligen. Spring selbst kann Ihnen hier nicht viel helfen, da es nichts von den anderen laufenden JVMs weiß. Quartz hingegen hat das Konzept eines geclusterten Schedulers.

Im Grunde müssen Sie eine einzige Datenbank einrichten, die von allen 4 JVMs gemeinsam genutzt werden kann. Diese wird als Scheduler für alle 4 Instanzen verwendet. Wenn ein Job geplant wird, wird er nur von einer der Instanzen unter Verwendung des Cluster-Schedulers ausgeführt.

Entnommen aus dem Wiki der Quartz-Website für Clustering ( http://www.opensymphony.com/quartz/wikidocs/ConfigJDBCJobStoreClustering.html ), ist dies eine Beispielkonfiguration für die Einrichtung des geclusterten Schedulers. Sie können diese Eigenschaften auch direkt in Spring einstellen, wenn Sie Ihren Scheduler auf diese Weise konfigurieren.

#============================================================================
# Configure Main Scheduler Properties  
#============================================================================

org.quartz.scheduler.instanceName = MyClusteredScheduler
org.quartz.scheduler.instanceId = AUTO

#============================================================================
# Configure ThreadPool  
#============================================================================

org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 25
org.quartz.threadPool.threadPriority = 5

#============================================================================
# Configure JobStore  
#============================================================================

org.quartz.jobStore.misfireThreshold = 60000

org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.oracle.OracleDelegate
org.quartz.jobStore.useProperties = false
org.quartz.jobStore.dataSource = myDS
org.quartz.jobStore.tablePrefix = QRTZ_

org.quartz.jobStore.isClustered = true
org.quartz.jobStore.clusterCheckinInterval = 20000

#============================================================================
# Configure Datasources  
#============================================================================

org.quartz.dataSource.myDS.driver = oracle.jdbc.driver.OracleDriver
org.quartz.dataSource.myDS.URL = jdbc:oracle:thin:@polarbear:1521:dev
org.quartz.dataSource.myDS.user = quartz
org.quartz.dataSource.myDS.password = quartz
org.quartz.dataSource.myDS.maxConnections = 5
org.quartz.dataSource.myDS.validationQuery=select 0 from dual

0 Stimmen

Ich danke Ihnen. Das ist sehr hilfreich für mich. Ich werde es ausprobieren.

0voto

davidsheldon Punkte 35065

In unserer Webanwendung verpacke ich jeden Auftrag in eine Klasse, die eine globale Sperre im gesamten Cluster anlegt (ich verwende Memcached, da es mir egal ist, ob die Aufgabe zu oft ausgeführt wird) und die Aufgabe nur ausführt, wenn sie die Sperre erhalten hat. Sie kann dann die Sperre freigeben, wenn die Aufgabe abgeschlossen ist (vergessen Sie nicht, dies in einer finally ).

Ein Vorteil des Wrappings der einzelnen Aufträge anstelle einer Änderung des Schedulers ist, dass einige Aufträge auf allen Rechnern und andere nur auf einem Rechner ausgeführt werden können.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X