Préface
Afin d'assurer une haute disponibilité et une concurrence élevée des applications, plusieurs nœuds sont généralement déployés; Pour les tâches de synchronisation, si chaque nœud effectue ses propres tâches de synchronisation, il consomme des ressources système d'une part.
D'un autre côté, certaines tâches sont exécutées plusieurs fois, ce qui peut entraîner des problèmes de logique d'application, donc un système de planification distribué est nécessaire pour coordonner chaque nœud pour effectuer des tâches de synchronisation.
Le printemps intègre le quartz
Quartz est un système de planification de tâches mature. Le printemps est compatible avec le quartz pour un développement facile. Voyons comment l'intégrer:
1. Fichier de dépendance de maven
<Dependances> <Dependency> <GroupId> org.springFramework </rom grouped> <Artifactid> printemps-core </ artifactid> <version> 4.3.5.release </dember> </dependency> <dependency> <proupId> org.springframework </proupId> <earttifactid> Spring-Context-Support </Retifactid> <version> 4.9. </Dependency> <Dedency> <GroupId> org.springFramework </rom grouped> <Artifactid> printemps-tx </ artifactid> <version> 4.3.5.release </ version> </dependency> <dependency> <proupId> org.springFramework </proupId> <Artifactid> Spring-JDBC </pterifactid> <fri version> 4.5. </Dependency> <Dedency> <GroupId> org.quartz-Scheduler </rom grouped> <ArtifActid> Quartz </ Artifactid> <Dersion> 2.2.3 </DERNIFRATIONS> </DENDEFENCE> <Dendency> <ProupId> MySQL </prôdId> <ArtifActid> MySQL-Connector-Java </RitifActid> </DENDENDENCES>
Les principales sont les bibliothèques liées au printemps, les bibliothèques de quartz et les bibliothèques de pilotes MySQL. Remarque: La planification distribuée nécessite l'utilisation de la base de données et MySQL est sélectionné ici;
2. Configurer le travail
Il existe deux façons de configurer des travaux, à savoir: MethodinVokJobDetailFactoryBean et JobdetailFactoryBean
2.1MethodinvokingJobdetailFactoryBean
Lorsque vous souhaitez appeler une méthode d'un bean spécifique, la configuration spécifique est la suivante:
<bean id = "firstTask"> <propriété name = "cibleObject" ref = "FirstService" /> <propriété name = "TargetMethod" value = "service" /> </ bea>
2.2JobdetailFactoryBean
Cette méthode est plus flexible et peut définir les paramètres de passage, comme suit:
<bean id = "firstTask"> <propriété name = "jobclass" value = "zh.maven.squartz.task.firstTask" /> <propriété name = "jobdatamap"> <map> <entrée key = "FirstService" value-ref = "FirstService" /> </ map> </ propriéne
La classe de tâches définie par JobClass hérite de QuartzJobbean et implémente la méthode exécutée; JobDatamap est utilisé pour transmettre des données au travail
3. Configurez les déclencheurs utilisés pour la planification
Deux types de déclencheurs sont également fournis: SimpleTriggerFactoryBean et CronTriggerFactoryBean
Concentrez-vous sur CronriggerFactoryBean, ce type est plus flexible, comme suit:
<bean id = "firstCrontrigger"> <propriété name = "jobdetail" ref = "firstTask" /> <propriété name = "cronexpression" value = "0/5 * *? * *" /> </ bean>
JobDetail spécifie le travail configuré à l'étape 2, et la cronexpression est configurée pour exécuter le travail toutes les 5 secondes;
4. Configurez le SchedulerFactoryBean du planificateur de quartz
Il existe également deux méthodes: la mémoire Ramjobstore et les méthodes de base de données
4.1 Mémoire Ramjobstore
Les informations liées à l'emploi sont stockées en mémoire, et chaque nœud stocke les siens, isole mutuellement et est configuré comme suit:
<an bean> <propriété name = "déclencheurs"> <s list> <ref bean = "firstCrontrigger" /> </sist> </ propriété> </bant>
4.2 Méthode de la base de données
Les informations pertinentes du travail sont stockées dans la base de données. Tous les nœuds partagent la base de données. Chaque nœud communique via la base de données pour s'assurer qu'un travail ne sera exécuté que sur un nœud en même temps.
Si un nœud échoue, le travail sera attribué à d'autres nœuds pour exécution. La configuration spécifique est la suivante:
<bean id = "dataSource" destrement-méthod = "close"> <propriété name = "driverclass" value = "com.mysql.jdbc.driver" /> <propriété name = "jdbcurl" value = "jdbc: mysql: // localhost: 3306 / quartz" /> <propriété name = "user" value = "root" /> <prewet name = "Value =" Value = "/>" /> "Value =" root "/>> <propriété =" Value = "Value =" /> "/>" Value " </Ean> <Ean> <propriété name = "dataSource" ref = "dataSource" /> <propriété name = "configLocation" value = "classpath: quartz.properties" /> <propriété name = "Triggers"> </bant> <ref bean = "firstCrontrigger" /> </sist> </ propriété> </ank
DataSource est utilisé pour configurer les sources de données et les informations liées à la table de données. Vous pouvez télécharger le package GZ sur le site officiel. Le fichier SQL est sous le chemin d'accès: docs / dbtables, qui fournit le fichier SQL pour la base de données grand public;
Le fichier quartz.properties configuré dans Configlocation se trouve dans le package org.quartz de Quartz.jar, qui fournit des données par défaut, telles que org.quartz.jobstore.class
org.quartz.jobstore.class: org.quartz.simpl.ramjobstore
Ici, vous devez copier Quartz.properties et apporter des modifications. Les modifications spécifiques sont les suivantes:
org.quartz.scheduler.instanceid: autoorg.quartz.jobstore.class: org.quartz.impl.jdbcjobstore.jobstoretxorg.quartz.jobstore.iscludered: trueorg.quartz.jobstore.clustercheckininterval: 1000
5. Catégories connexes
La classe publique FirstTask étend QuartzJobbean {private FirstService FirstService; @Override Protected void executeInternal (JobExecutionContext Context) lève JobExEcutionException {FirstService.Service (); } public void setFirstService (FirstService FirstService) {this.firstService = FirstService; }}FirstTask hérite de QuartzJobbean, implémente la méthode d'exécution et d'appel FirstService
classe publique FirstService implémente Serializable {private statique final long SerialVersionUID = 1l; public void Service () {System.out.println (new SimpledateFormat ("yyymmdd hh: mm: ss"). format (new Date ()) + "--- start FirstService"); essayez {thread.sleep (2000); } catch (InterruptedException e) {e.printStackTrace (); } System.out.println (new SimpledateFormat ("YyyMMDD HH: MM: SS"). Format (new Date ()) + "--- End FirstService"); }}FirstService doit fournir une interface de sérialisation car elle doit être enregistrée dans la base de données;
public class app {public static void main (String [] args) {abstractApplicationContext context = new ClassPathXmlApplicationContext ("Quartz.xml"); }}La classe principale est utilisée pour charger le fichier de configuration du quartz;
Test de planification distribuée
1. Démarrez l'application deux fois en même temps et observez le journal:
20180405 14:48:10 --- Start FirstService
20180405 14:48:12 ---- End FirstService
20180405 14:48:15 --- Start FirstService
20180405 14:48:17 ---- End FirstService
Parmi eux, A1 a une sortie logarithmique, mais A2 ne le fait pas; Lorsque A1 est arrêté, A2 a une sortie de journal;
2. Ajoutez de nouveaux travaux et créez de nouveaux: SecondTask et SecondService respectivement. Ajoutez des fichiers de configuration pertinents en même temps. Démarrez l'application deux fois et observez le journal:
Le journal A1 est le suivant:
20180405 15:03:15 --- Start FirstService
20180405 15:03:15 --- Démarrer SecondService
20180405 15:03:17 ---- End FirstService
20180405 15:03:17 --- End SecondService
20180405 15:03:20 --- Démarrez FirstService
20180405 15:03:22 ---- End FirstService
20180405 15:03:25 --- Start FirstService
20180405 15:03:27 ---- End FirstService
Le journal A2 est le suivant:
20180405 15:03:20 --- Démarrez SecondService
20180405 15:03:22 --- End SecondService
20180405 15:03:25 --- Start SecondService
20180405 15:03:27 --- End SecondService
On peut constater que A1 et A2 ont des tâches d'exécution, mais la même tâche ne sera exécutée que sur un seul nœud en même temps, et il est possible d'être affecté à d'autres nœuds une fois l'exécution terminée;
3. Si le temps d'intervalle est inférieur au temps d'exécution de la tâche, par exemple, ici est changé pour dormir (6000)
Le journal A1 est le suivant:
20180405 15:14:40 --- Start FirstService
20180405 15:14:45 --- Start FirstService
20180405 15:14:46 ---- End FirstService
20180405 15:14:50 --- Start FirstService
20180405 15:14:50 --- Démarrer SecondService
20180405 15:14:51 --- End FirstService
Le journal A2 est le suivant:
20180405 15:14:40 --- Démarrer SecondService
20180405 15:14:45 --- Démarrer SecondService
20180405 15:14:46 --- End SecondService
20180405 15:14:51 --- End SecondService
L'intervalle est de 5 secondes, tandis que l'exécution de la tâche prend 6 secondes. En observant le journal, vous pouvez constater que la tâche ne s'est pas encore terminée et qu'une nouvelle tâche a commencé. Cette situation peut entraîner des problèmes logiques dans l'application, ce qui est en fait la question de savoir si la tâche peut soutenir la série;
4. @DisallowConcurrentExecution Annotation assure la sérialisation des tâches
Ajoutez @disallowconcurrentExecution Annotation sur FirstTask et SecondTask respectivement, et les résultats du journal sont les suivants:
Le journal A1 est le suivant:
20180405 15:32:45 --- Start FirstService
20180405 15:32:51 --- End FirstService
20180405 15:32:51 --- Start FirstService
20180405 15:32:51 --- Démarrer SecondService
20180405 15:32:57 ---- End FirstService
20180405 15:32:57 --- End SecondService
20180405 15:32:57 --- Start FirstService
20180405 15:32:57 --- Start SecondService
Le journal A2 est le suivant:
20180405 15:32:45 --- Démarrer SecondService
20180405 15:32:51 --- End SecondService
En observant les journaux, vous pouvez constater que la tâche ne lancera qu'une nouvelle tâche après la fin et réaliser la sérialisation de la tâche;
Résumer
Cet article vise à avoir une compréhension intuitive de la planification distribuée Spring + Quartz et résoudre le problème grâce à une utilisation réelle. Bien sûr, il peut y avoir de nombreuses questions telles que la façon dont elle est prévue, ce qui se passera si la base de données est accrochée, etc., et une compréhension plus approfondie est nécessaire.
Ce qui précède est tout le contenu de cet article. J'espère que cela sera utile à l'apprentissage de tous et j'espère que tout le monde soutiendra davantage Wulin.com.