1. grundlegende Implementierungsprinzip der Quartz -Aufgabeplanung
Quartz ist ein Open -Source -Projekt im Bereich der Aufgabenplanung durch OpenSymphony, das vollständig auf der Java -Implementierung basiert. Als ausgezeichnetes Open -Source -Scheduling -Framework hat Quartz die folgenden Funktionen:
(1) leistungsstarke Planungsfunktionen wie die Unterstützung einer Vielzahl von Planungsmethoden können verschiedene konventionelle und besondere Bedürfnisse erfüllen.
(2) flexible Anwendungsmethoden, z. B. die Unterstützung mehrerer Kombinationen von Aufgaben und Planung sowie die Unterstützung mehrerer Speichermethoden zur Planung von Daten;
(3) Verteilte und Clustering -Funktionen haben Terrakotta seine ursprünglichen Funktionen nach der Akquisition weiter verbessert. Dieser Artikel summiert sich zu diesem Teil.
1,1 Quarzkernelemente
Die Kernelemente der Quartz-Aufgabenplanung sind: Scheduler-Task-Scheduler, Trigger-Trigger und Job-Task. Wo Trigger und Job Metadaten für die Aufgabenplanung sind, und Scheduler ist der Controller, der tatsächlich die Planung durchführt.
Trigger ist ein Element, das verwendet wird, um die Zeitplanungszeit zu definieren, dh gemäß den Zeitregeln, die die Aufgabe ausgeführt wird. In Quartz gibt es vier Arten von Triggern: Simpligger, Crontirgger, DateIntervaltrigger und NthincludeddayTrigger. Diese vier Auslöser können die meisten Anforderungen von Unternehmensanwendungen erfüllen.
Job wird verwendet, um geplante Aufgaben darzustellen. Es gibt hauptsächlich zwei Arten von Arbeitsplätzen: Staatenlos und staatlich. Für den gleichen Auslöser können staatliche Jobs nicht parallel ausgeführt werden. Erst nachdem die letzte Ausführung der Aufgabe ausgeführt wurde, kann die nächste Ausführung ausgelöst werden. HOB hat zwei Hauptattribute: volatil und haltbar, wo flüchtig bedeutet, ob die Aufgabe in der Datenbankspeicherung bestehen bleibt, während Langlebigkeit bedeutet, ob die Aufgabe beibehalten wird, wenn keine Auslöser Assoziation vorliegt. Beide sind bestehen oder erhalten, wenn der Wert wahr ist. Ein Job kann mit mehreren Triggern verbunden werden, aber ein Auslöser kann nur einen Job assoziieren.
Scheduler wird von Scheduler Factory erstellt: DirectSchedulerFactory oder StdSchedulerFactory. Die zweite Fabrik, StdSchedulerFactory, wird häufiger verwendet, da Regisseure SchedulerFaktor nicht bequem genug sind, und viele detaillierte manuelle Codierungseinstellungen sind erforderlich. Es gibt drei Haupttypen von Scheduler: RemotemBeansScheduler, Remotesplaner und StdScheduler.
Die Beziehung zwischen den Kernelementen von Quarz ist in Abbildung 1.1 dargestellt:
Abbildung 1.1 Kernelement -Beziehungsdiagramm
1,2 Quarz -Thread -Ansicht
In Quartz gibt es zwei Arten von Threads, Scheduler -Scheduler -Threads und Thread -Threads, bei denen Threads Task -Execution normalerweise einen Thread -Pool verwenden, um eine Gruppe von Threads zu verwalten.
Abbildung 1.2 Quarzfadenansicht
Es gibt zwei Hauptfäden für Scheduler: Threads, die regelmäßige Planung und Threads ausführen, die Fehlanfänger ausführen. Der reguläre Versandfaden befragt alle gespeicherten Auslöser. Wenn es einen Auslöser gibt, der ausgelöst werden muss, dh die Zeit des nächsten Auslösers erreicht, erhält er einen Leerlauf -Thread aus dem Task -Ausführungs -Thread -Pool, um die mit dem Abzug zugeordnete Aufgabe auszuführen. Der Fehlzündungs -Thread scannt alle Auslöser, um festzustellen, ob es einen Fehlfeuchtigkeitsstrigger gibt. In diesem Fall wird es nach der Fehlzündungspolitik getrennt gehandhabt (jetzt Feuer oder warte auf das nächste Feuer).
1.3 Quarzdatenspeicher
Die Auslöser und Jobs in Quarz müssen gespeichert werden, bevor sie verwendet werden können. In Quartz gibt es zwei Speichermethoden: Ramjobstore und JobStoresupport, in denen Ramjobstore Stores und Jobs im Speicher auslöst und Jobs auslöst, während JobStoresupport Stores und Jobs in Datenbank basierend auf JDBC auslöst. Ramjobstore ist ein sehr schneller Zugriff, aber da alle Daten nach dem Anhalten des Systems verloren gehen, muss JobStoresupport in Clusteranwendungen verwendet werden.
2. Quarz -Cluster -Prinzip 2.1 Quarz -Clusterarchitektur
Jeder Knoten in einem Quarzcluster ist eine unabhängige Quarzanwendung, die wiederum andere Knoten verwaltet. Dies bedeutet, dass Sie jeden Knoten separat starten oder stoppen müssen. Im Quarzcluster kommunizieren unabhängige Quarzknoten nicht mit einem anderen Knoten oder Verwaltungsknoten, sondern einer anderen Quarzanwendung in derselben Datenbanktabelle, wie in Abbildung 2.1 gezeigt.
Abbildung 2.1 Quarz -Clusterarchitektur
2,2 Quarz-Cluster-verwandte Datenbanktabellen
Da der Quartz -Cluster von der Datenbank abhängt, müssen zunächst die Quartz -Datenbanktabelle erstellt werden. Das Quartz Release -Paket enthält SQL -Skripte für alle unterstützten Datenbankplattformen. Diese SQL -Skripte werden im Verzeichnis <quartz_home>/docs/dbtable gespeichert. Die hier verwendete Quartz -Version 1.8.4 enthält insgesamt 12 Tabellen. Die Anzahl der Tabellen kann in verschiedenen Versionen unterschiedlich sein. Die Datenbank ist MySQL und verwendet tables_mysql.sql, um eine Datenbanktabelle zu erstellen. Alle Tabellen sind in Abbildung 2.2 dargestellt, und eine kurze Einführung in diese Tabellen ist in Abbildung 2.3 dargestellt.
Abbildung 2.2 Tabellen, die in Quartz 1.8.4 in der MySQL -Datenbank erzeugt wurden
Abbildung 2.3 Einführung in die Quarzdatentabelle
2.2.1 Scheduler -Status Tabelle (qrtz_scheduler_state)
Beschreibung: In den Informationen zur Knoteninstanz im Cluster liest Quartz die Informationen dieser Tabelle regelmäßig, um den aktuellen Status jeder Instanz im Cluster zu bestimmen.
Instance_Name: Der von org.quartz.scheduler.instanceId in der Konfigurationsdatei konfigurierte Name. Wenn Quartz auf automatisch eingestellt ist, generiert er einen Namen basierend auf dem physischen Maschinennamen und der aktuellen Zeit.
Last_Checkin_Time: Letzte Check-in-Zeit
checkin_interval: Check-in-Intervallzeit
2.2.2 Trigger- und Task -Association -Tabelle (qrtz_fired_triggers)
Speichert Statussinformationen im Zusammenhang mit den ausgelösten Auslöser- und Ausführungsinformationen des zugehörigen Jobs.
2.2.3 Triggerinformationstabelle (qrtz_triggers)
Trigger_Name: Auslösername, der Benutzer kann den Namen nach Belieben anpassen, keine erzwungenen Anforderungen
Trigger_Group: Der Name der Triggergruppe, die der Benutzer nach Belieben anpassen kann, und es gibt keine erzwungene Anforderung.
Job_Name: Fremdschlüssel von qrtz_job_details table Job_name
job_group: qrtz_job_details table Job_group Fremdschlüssel
Trigger_State: Der aktuelle Auslöserstatus wird auf erworbene gesetzt. Wenn es auf das Warten eingestellt ist, wird der Job nicht ausgelöst.
Trigger_Cron: Triggertyp unter Verwendung des Cron -Ausdrucks
2.2.4 Task Details Tabelle (qrtz_job_details)
HINWEIS: Speichern Sie die Jobdetails, die Tabelle muss vom Benutzer gemäß der tatsächlichen Situation initialisiert werden
Job_Name: Der Name des Jobs im Cluster. Der Benutzer kann den Namen nach Belieben anpassen, ohne erzwungene Anforderungen.
Job_Group: Der Name der Gruppe, zu der der Job in den Cluster gehört, der vom Benutzer nach Belieben angepasst wird, und es gibt keine erzwungenen Anforderungen.
job_class_name: Der komplette Paketame der Job -Implementierungsklasse im Cluster. Quartz findet die Jobklasse basierend auf diesem Weg zum Klassenpfad.
is_durable: Ob bestehen, diese Eigenschaft auf 1 festlegen, Quartz bleibt den Job in der Datenbank bestehen
Job_data: Ein Blob -Feld, in dem es angestrahlt wurde, ständige Jobobjekte.
2.2.5 Berechtigungsinformationstabelle (QRTZ_LOCKS)
HINWEIS: In tables_oracle.sql gibt es eine entsprechende DML -Initialisierung, wie in Abbildung 2.4 gezeigt.
Abbildung 2.4 Initialisierungsinformationen in der Quartz -Berechtigungsinformationstabelle
2.3 Quarzplaner -Startprozess im Cluster
Quartz Scheduler selbst bemerkt nicht, dass es sich anclustert, und nur der für Scheduler konfigurierte JDBC -Jobstore wird es kennen. Wenn der Quartz -Scheduler startet, ruft er die SchedumlerStarted () -Methode des Jobstore auf, die dem Jobstore -Scheduler mitteilt, dass er begonnen hat. Die PlanerStarted () -Methode wird in der JobStoresupport -Klasse implementiert. Die JobStoresupport -Klasse bestimmt, ob die Scheduler -Instanz basierend auf den Einstellungen in der Datei quartz.properties am Cluster teilnimmt. Wenn der Cluster konfiguriert ist, wird eine Instanz einer neuen Clustermanager -Klasse erstellt, initialisiert und gestartet. ClusterManager ist eine Inline-Klasse in der JobStoresupport-Klasse, die Java.lang.thread erbt. Es wird regelmäßig ausgeführt und führt Check-in-Funktionen für die Scheduler-Instanz aus. Scheduler muss auch überprüfen, ob andere Clusterknoten fehlgeschlagen sind. Der Ausführungszyklus für Check-in-Betrieb ist in quartz.properties konfiguriert.
2.4 Erkennen eines fehlgeschlagenen Scheduler -Knotens
Wenn eine Scheduler-Instanz einen Check-in ausführt, wird überprüft, ob andere Scheduler-Instanzen zum Zeitpunkt der Erwartung nicht eingecheckt wurden. Dies wird bestimmt, indem überprüft wird, ob der Wert des in der Spalte last_chedk_time in der Tabelle Scheduler_State aufgezeichneten Schedulers früher als org.quartz.jobstore.clustercheckinInterval ist. Wenn ein oder mehrere Knoten nicht zu einem vorgegebenen Zeitpunkt eingecheckt wurden, geht der laufende Scheduler davon aus, dass er fehlgeschlagen ist.
2.5 Jobs aus fehlgeschlagenen Fällen wiederherstellen
Wenn eine Sheduler -Instanz bei der Ausführung eines Jobs fehlschlägt, ist es möglich, dass eine andere Arbeitsplaner -Instanz den Job annimmt und ihn erneut ausführt. Um dieses Verhalten zu erreichen, muss die für das JobDetail -Objekt konfigurierte Jobwiederherstellungseigenschaft auf True (Job.SetRequestSRecovery (TRUE)) festgelegt werden. Wenn die wiederherstellbare Eigenschaft auf False festgelegt ist (Standard ist falsch), wird sie nicht erneut ausgelöst, wenn ein Scheduler den Job nicht ausführt. Es wird von einer anderen Scheduler -Instanz zur nächsten Auslöserzeit ausgelöst. Wie schnell die Scheduler-Instanz erkannt werden kann, nachdem ein Fehler des Eincheckintervalls jedes Schedulers abhängt (d. H. Org.quartz.JOBSTORE.CLUSTERCHECKININERVAL, erwähnt in 2.3).
3. Quarz -Cluster -Instanz (Quarz+Feder)
3.1 Frühling unvereinbar mit Quarzproblemen
Der Frühling unterstützt Quarz seit 2.0.2 nicht mehr. Insbesondere, wenn Quartz+Spring die Aufgabe von Quartz in die Datenbank instanziiert, tritt ein serialisierbarer Fehler auf:
<bean id = "JobTask"> <Eigenschaft name = "targetObject"> <ref bean = "quartzjob"/> </property> <Eigenschaft name = "targetMethod"> <wert> Ausführen </value> </property> </bean>
Die Methodinvoking -Methode in der MethodeinvokingjobDetailFactoryBean -Klasse unterstützt keine Serialisierung, sodass sie beim Serialisieren der Quarzaufgabe in die Datenbank einen Fehler aufwirft.
Lösen Sie zunächst das Problem der MethodinvokingjobDetailFactoryBean. Ohne den Frühlingsquellcode zu ändern, können Sie diese Klasse vermeiden und JobDetail direkt anrufen. Durch die Verwendung von Jobdetail -Implementierung müssen Sie jedoch die Logik des Mothodinvokings selbst implementieren. Sie können die JobClass- und JobDataasasMap -Eigenschaften von JobDetail nutzen, um eine Fabrik (Manager) anzupassen, um denselben Zweck zu erreichen. In diesem Beispiel wird beispielsweise eine neue MyDetailquartzjobbean erstellt, um diese Funktion zu implementieren.
3.2 myDetailquartzjobbean.java -Datei
Paket org.lxh.mvc.jobbean; import java.lang.reflect.method; import org.apache.commons.logging.log; import org.apache.commons.logging.logfactory; org.springFramework.context.ApplicationContext; import org.springframework.Scheduling.quartz.quartzjobbean; public class myDetailquartzjobbean erweitert Quartzjobbean {Protected Final Logger = LogFactory.GetClog (GetClASS (); private String targetObject; private String targetMethod; private applicationContext ctx; Protected void executeInternal (JobExecutionContext -Kontext) löst JobExecutionException {try {logger.info aus ("ausführen [" + targetObject + "] sofort >>>>>"); Object oarGetObject = ctx.getbean (targetObject); Methode M = NULL; try {m = oarGetObject.getClass (). getMethod (targetMethod, neue Klasse [] {}); M.Invoke (oarGetObject, neues Objekt [] {}); } catch (SecurityException e) {logger.Error (e); } catch (NoSuchMethodException e) {logger.Error (e); }} catch (Ausnahme e) {neue jobexecutionException (e) werfen; }} public void setApplicationContext (ApplicationContext applicationContext) {this.ctx = ApplicationContext; } public void settargetObject (String targetObject) {this.targetObject = targetObject; } public void settargetMethod (String targetMethod) {this.targetMethod = targetMethod; }}3.3 REAL -Job -Implementierungsklasse
In der Testklasse wird die Funktion des Druckens der aktuellen Zeit des Systems einfach implementiert.
Paket org.lxh.mvc.job; import Java.io.Serializable; import Java.util.date; import org.apache.commons.logging.log; Private statische endgültige lange Serialversionuid = -2073310586499744415L; public void execute () {date date = new Date (); System.out.println (Date.tolocalestring ()); }}3.4 Konfigurieren Sie die Datei quartz.xml
<bean id = "test" scope = "prototype"> </bean> <bean id = "testjobtask"> <Eigenschaft name = "JobClass"> <value> org.lxh.mvc.jobbean.mydetailquartzjobbean </value> </value> </property adiotdel -taga = "jobataasbasMap"> <"</" <"<" <"<" <"<" <"<" <"<" <MaptataasMap "> <" <"<" <"<" <"<" <"<"> <MaptaTaMaps "> <MaptaMaps"> <MaptaStaasMap "> <" </". key = "targetMethod" value = "execute"/> </map> </property> </bean> <bean name = "testtrigger"> <Eigenschaft name = "JobDetail" ref = "testJoBtask"/> <Eigenschaft name = "cronexpression" value = "0/1 * * * *?" /> </bean> <bean id = "quartzScheduler"> <Eigenschaft name = "configLocation" value = "classPath: quartz.properties"/> <Eigenschaft name = "Triggers"> <list> <ref bean = "testtrigger"/> </list> </Property> <Eigenschaftsname = "ApplicationContexTextextextextextKey".
3.5 Test
Der Code und die Konfiguration von Servera und ServerB sind genau gleich. Start Servera zuerst und dann Serverb starten. Nach dem Abschalten des Servers überwacht ServerB das Herunterfahren und übernimmt den Auftrag, der auf Servera ausführt, und setzt die Ausführung fort.
4. Quarz -Cluster -Instanz (einzelner Quarz)
Obwohl wir die Cluster -Konfiguration von Spring+Quartz implementiert haben, wird diese Methode aufgrund von Kompatibilitätsproblemen zwischen Spring und Quarz weiterhin nicht empfohlen. In diesem Abschnitt haben wir einen Cluster implementiert, der separat mit Quarz konfiguriert ist, was im Vergleich zu Spring+Quartz einfach und stabil ist.
4.1 Ingenieurstruktur
Wir verwenden Quartz allein, um seine Clusterfunktionen, die Codestruktur und die erforderlichen JAR-Pakete von Drittanbietern zu implementieren, wie in Abbildung 3.1 gezeigt. Unter ihnen: MySQL-Version: 5.1.52 und MySQL-Treiberversion: MySQL-Connector-Java-5.1.5-im-Bin.jar (für 5.1.52 wird empfohlen, diese Version des Treibers zu verwenden, da ein Fehler in Quartz vorhanden ist, dass es bei einigen MySQL-Treibern normalerweise nicht in Kombination in Kombination geleitet wird).
Abbildung 4.1 Quarz-Cluster-Ingenieurstruktur und erforderliche JAR-Pakete von Drittanbietern
Unter ihnen ist Quartz.Properties die Quartz -Konfigurationsdatei und im SRC -Verzeichnis platziert. Wenn es keine solche Datei gibt, lädt Quartz die Datei quartz.properties automatisch in das JAR -Paket. SimpleRecoveryjob.java und SimplyRecoverySfuljob.java sind zwei Jobs; Cluperexample.java schreibt Planungsinformationen, Auslösermechanismus und entsprechende Testhauptfunktionen.
4.2 Konfigurationsdatei quarz.properties
Der Standarddateiname quartz.properties wird verwendet, um die Clusterfunktion zu aktivieren, indem die Eigenschaft "org.quartz.jobstore.isclustered" auf "true" festgelegt wird. Jede Instanz im Cluster muss über eine eindeutige "Instanz -ID" ("org.quartz.scheduler.instanceId" -Mobilie) verfügen, aber es sollte denselben "Scheduler -Instanznamen" haben ("org.quartz.scheduler.instoncnenname"), was bedeutet, dass jede Instanz im Cluster dieselbe Quartz.Properties -Konfigurationsdatei verwenden muss. Mit Ausnahme der folgenden Ausnahmen muss der Inhalt der Konfigurationsdatei gleich sein:
A. Gewindepoolgröße.
B. Unterschiedliche "org.quartz.scheduler.instanceId" -attributwerte (einfach auf "auto" festgelegt).
#=================================================================== ====================================================================== ====================================================================== ====================================================================== ====================================================================== ====================================================================== ====================================================================== ====================================================================== AUTO#============================================================================================== ==========================================================ieben org.quartz.jobstore.impl.jdbcjobstore.jobstoretxorg.quartz.jobstore.driverdelegateclass = org.quartz.impl.jdbcjobstore.stdjdbcdelegateorg.quartz.jobstore.table.table.table.table.table.table.table.table.table.table.table.table.table.table.table.table.table.table.table.table.table.table Qrtz_org.quartz.jobstore.isclustered = trueorg.quartz.jobstore.clustercheckinInterval = 10000 org.quartz.jobstore.datasource = myds #=================================================================================================ieben ===========================================================================================================ieben ===========================================================================================================ieben ===========================================================================================================ieben #====================================================ieben com.mysql.jdbc.driverorg.quartz.datasource.myds.url = jdbc: mysql: //192.168.31.18: 3306/test? UseUnicode = true & charakteristisch = utf-8org.quartz.dataSource.myds.usSource.usource.usource.usource.usource.usource.usource.usource.usource.user rootorg.quartz.datasource.myds.password = 123456org.quartz.datasource.myds.maxConnections = 30#=========================================================== ================================================================= ================================================================= ================================================================= ================================================================= ================================================================= ================================================================= ================================================================= org.quartz.simpl.simpletheadpoolorg.quartz.threadpool.threadcount = 5org.quartz.threadpool.threadpriority = 5org.quartz.threadpool.ThreadsinheritContextClassOlaNtheadThead = True trueadpool. theadpool.ThreadsinheritContextClasseroLeThead = true = trueDpool = trueadpool.
4.3 cluperexample.java -Datei
Paketcluster; import Java.util.date; import org.quartz.jobdetail; import org.quartz.scheduler; import org.quartz.schedulerFactory; {System.out.println ("**** vorhandene Jobs/Trigger *****"); // jobs sciples string [] gruppen = insplaner.gettriggerGroupnames (); für (int i = 0; i <Groups.length; i ++) {String [] names = Inpleduler.getTriggerNames (Gruppen [i]); für (int j = 0; j <names.length; j ++) {Inpleduler.UnSchedulejob (Namen [j], Gruppen [i]); }} // Jobs gruppen löschen = Inplaner.getJobGroupnames (); für (int i = 0; i <Groups.length; i ++) {String [] names = Inplaner.getJobnames (Gruppen [i]); für (int j = 0; j <names.length; j ++) {Inplaner.deletejob (Namen [j], Gruppen [i]); }}} public void run (boolean geknüpftjobs, boolean InSchedulejobs) löst Ausnahme aus {// Zuerst müssen wir einen Verweis auf einen Scheduler SchedulerFactory sf = new StdSchedulerFactory () erhalten; Scheduler plant = sf.getScheduler (); if (windeljobs) {cleanup (artplan); } System.out.println ("-------------------------------"); if (inSchedulejobs) { System.out.println("------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Rexecute diesen Job, wenn es in Arbeit war, wenn der Scheduler ausging. bis Rexecute diesen Job, wenn es in Arbeit war, wenn der Scheduler nach unten ging. Trigger. Sched.Start (); Thread.sleep (3600L * 1000L); System.out.println("--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Args.Length; }}4.4 SimplyRecoveryjob.java
Paketcluster; import Java.io.Serializable; Import Java.util.date; import org.apache.commons.logging.log; jobs that you want to execute repeatedly, write the relevant code in the execute method, the premise is: implement the Job interface//As for when the SimpleJob class is instantiated and when the execute method is called, we don’t need to pay attention to it, and leave it to Quartzpublic class SimpleRecoveryJob implements Job, Serializable { private static Log _log = LogFactory.getLog(SimpleRecoveryJob.class); public SimpleRecoveryJOB () {} public void execute (JobExecutionContext -Kontext) löst JobExecutionException aus {// Dieser Job druckt einfach den Jobnamen und die Zeit, in der der Job String JobName = context.getjobdetail (). Getfullname () ausführt; System.out.println ("Job 11111111111111111 SimpleRecoveryJOB sagt:" + JobName + "Ausführung am" + New Date ()); }}4.5 Betriebsergebnisse
Die Konfiguration und der Code in Server A und Server B sind genau gleich. Auslaufmethode: Fügen Sie clusterExample.java auf jedem Host aus, fügen Sie die Aufgabe dem Zeitplan hinzu und beobachten Sie die Run -Ergebnisse:
Run Servera ausführen, die Ergebnisse sind in Abbildung 4.2 dargestellt.
Abbildung 4.2 Servera -Betriebsergebnis 1
Nach dem Einschalten von ServerB ist die Ausgabe von Servera und ServerB in den Abbildungen 4.3 und 4.4 angezeigt.
Abbildung 4.3 Servera Auslaufergebnis 2
Abbildung 4.4 Serverb -Betriebsergebnis 1
Aus den Abbildungen 4.3 und 4.4 ist ersichtlich, dass das System nach dem Einschalten von ServerB die Verantwortung für das Gleichgewicht automatisch erkennt und ServerB Job1 übernimmt. Nach dem Abschalten von Servera sind die laufenden Ergebnisse von ServerB in Abbildung 4.5 dargestellt.
Abbildung 4.5 Serverb -Betriebsergebnis 2
Wie aus Abbildung 4.5 hervorgeht, kann ServerB erkennen, dass Servera verloren geht, das Task -Job2 übernehmen und Servera an den Job2 verlieren, der während dieser Ausnahmezeit ausgeführt werden muss.
5. Dinge zu beachten
5.1 Zeitsynchronisationsproblem
Quartz ist es egal, ob Sie Knoten auf denselben oder verschiedenen Maschinen ausführen. Wenn ein Cluster auf verschiedenen Maschinen platziert wird, wird er als horizontaler Cluster bezeichnet. Wenn ein Knoten auf derselben Maschine läuft, wird er als vertikaler Cluster bezeichnet. Für vertikale Cluster gibt es ein Problem des Versagens. Dies ist für Anwendungen mit hoher Verfügbarkeit nicht akzeptabel, da nach dem Absturz der Maschine alle Knoten beendet werden. Für horizontale Cluster gibt es ein Problem der Zeitsynchronisation.
Der Knoten verwendet einen Zeitstempel, um andere Instanzen seiner eigenen letzten Check-in-Zeit zu benachrichtigen. Wenn die Uhr des Knotens auf die zukünftige Zeit eingestellt ist, wird der laufende Scheduler nicht mehr erkennen, dass der Knoten gefallen ist. Wenn andererseits die Uhr eines Knotens auf vergangene Zeit eingestellt ist, wird der andere Knoten möglicherweise feststellen, dass der Knoten herausgefallen ist, und versucht, seinen Job zu übernehmen und wiederzugeben. Der einfachste Weg, eine Computeruhr zu synchronisieren, besteht darin, einen Internet -Zeitserver zu verwenden.
5.2 Das Problem von Knoten, die um Arbeitsplätze konkurrieren
Da Quartz einen zufälligen Lastausgleichsalgorithmus verwendet, wird der Job auf zufällige Weise von verschiedenen Instanzen ausgeführt. Die offizielle Website von Quartz erwähnte, dass es derzeit keine Methode gibt, um einem bestimmten Knoten im Cluster einen Job zuzuweisen (PIN).
5.3 Ausgabe, um die Jobliste von Cluster zu erhalten
Wenn Sie die Datenbankabfrage nicht direkt eingeben, gibt es keine einfache Möglichkeit, eine Liste aller ausführenden Jobs im Cluster zu erhalten. Wenn Sie eine Scheduler -Instanz anfordern, erhalten Sie nur eine Liste von Jobs, die in dieser Instanz ausgeführt werden. Die offizielle Quartz -Website empfiehlt, dass Sie alle Stelleninformationen aus der entsprechenden Tabelle erhalten können, indem Sie einen JDBC -Code zum Zugriff auf die Datenbank schreiben.
Zusammenfassen
Das obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, dass der Inhalt dieses Artikels einen gewissen Referenzwert für das Studium oder die Arbeit eines jeden hat. Wenn Sie Fragen haben, können Sie eine Nachricht zur Kommunikation überlassen. Vielen Dank für Ihre Unterstützung bei Wulin.com.