Springboot Integrated quartz cluster mode (phase III)

Source: Internet
Author: User
Tags create index redis redis cluster
springboot Integrated Quartz cluster mode (phase III) This issue will provide quartz clustering capabilitiesCluster Case Analysis:
The previous issue of the mail delivery function, if the service needs to deploy multi-node, but the scheduled task does not support the cluster, so the multi-node timing task will be run at the same time,
If the user is sent an e-mail notification, in this case, the user will be sent two times the same message, n nodes will send n times mail, serious non-compliance with the business scenario,
If the ability to provide the cluster, the multi-node should share the work of sending mail instead of each node do duplication of work, so in the deployment of multi-node timing tasks also need to provide clustering capabilities. Personal Insights:
Quartz cluster is divided into horizontal cluster and vertical cluster, the horizontal cluster will be deployed on different servers, and the biggest problem of horizontal cluster is the clock synchronization problem.
Quartz cluster is strongly required clock synchronization, if the clock can not be synchronized, it will lead to the cluster node state disorder, causing unpredictable consequences, please self-search server clock synchronization,
If the clock can be synchronized, the level cluster can guarantee the service reliability, one node hangs or one of the servers down, the other nodes are still normal service; a vertical cluster is a cluster of nodes deployed on the same server.
Clock synchronization is naturally not a problem, but there is a single point of failure, and server downtime can seriously impact service availability. Therefore, in order to consider the actual situation of the cluster solution because the cluster is strongly required clock synchronization, so whether it is a vertical cluster or a horizontal cluster, the local development must not be connected to the online environment (local is the cluster mode), which will inevitably destroy the cluster, but if the local non-cluster mode,
You can connect to the online environment depending on the situation. Quartz cluster and Redis cluster implementation is different, Redis cluster requires communication between nodes, each node needs to know the status of other nodes, and the implementation of quartz cluster
The way lies in 11 tables, the cluster nodes do not communicate with each other, but by the timing of the task of persistent lock-up way to achieve the cluster. The consequences of destroying a cluster are usually a deadlock or a state disorder. Each node is unavailable or some of these nodes can use some or all of the scheduled tasks 1.11 Tables required to create a cluster
T_b_qrtz_blob_triggers
t_b_qrtz_calendars
t_b_qrtz_cron_triggers
t_b_qrtz_fired_triggers
t_b_ Qrtz_job_details
t_b_qrtz_locks
t_b_qrtz_paused_trigger_grps
t_b_qrtz_scheduler_state
T_b_qrtz _simple_triggers
t_b_qrtz_simprop_triggers
t_b_qrtz_triggers
2. Cluster-built table SQL
drop table if exists t_b_qrtz_fired_triggers;
drop table if exists T_b_qrtz_paused_trigger_grps;
drop table if exists t_b_qrtz_scheduler_state;
drop table if exists t_b_qrtz_locks;
drop table if exists t_b_qrtz_simple_triggers;
drop table if exists t_b_qrtz_simprop_triggers;
drop table if exists t_b_qrtz_cron_triggers;
drop table if exists t_b_qrtz_blob_triggers;
drop table if exists t_b_qrtz_triggers;
drop table if exists t_b_qrtz_job_details;

drop table if exists t_b_qrtz_calendars; CREATE TABLE T_b_qrtz_job_details (sched_name varchar) NOT NULL, Job_name varchar ($) NOT NULL, Job_group Varch AR (+) NOT NULL, description varchar (+) NULL, Job_class_name varchar (+) NOT NULL, is_durable varchar (1) Not nul
  L, Is_nonconcurrent varchar (1) is not NULL, Is_update_data varchar (1) is not NULL, requests_recovery varchar (1) is not NULL,

Job_data blob NULL, PRIMARY KEY (Sched_name,job_name,job_group)) Engine=innodb; CREATE TABLE T_b_qrtz_triggers (sched_name varchar (120) NOT NULL, Trigger_name varchar ($) NOT NULL, Trigger_group varchar ($) NOT NULL, Job_name varchar ($) NOT NULL , Job_group varchar ($) NOT NULL, description varchar (+) NULL, next_fire_time bigint (All) null, Prev_fire_time b Igint () NULL, priority integer NULL, trigger_state varchar (+) NOT NULL, Trigger_type varchar (8) is not NULL, start _time bigint (2) NOT NULL, end_time bigint (All) null, Calendar_name varchar ($) NULL, MISFIRE_INSTR smallint () null , Job_data blob null, PRIMARY KEY (Sched_name,trigger_name,trigger_group), foreign key (Sched_name,job_name,job_grou

p) References t_b_qrtz_job_details (sched_name,job_name,job_group)) Engine=innodb; CREATE TABLE T_b_qrtz_simple_triggers (sched_name varchar) NOT NULL, Trigger_name varchar ($) NOT NULL, Trigge  R_group varchar ($) NOT NULL, repeat_count bigint (7) is not NULL, repeat_interval bigint (+) not NULL, times_triggered BigInt (Ten) not NULL, PRIMARY key (Sched_name,trigger_namE,trigger_group), foreign Key (Sched_name,trigger_name,trigger_group) references T_b_qrtz_triggers (Sched_name,

Trigger_name,trigger_group)) Engine=innodb; CREATE TABLE T_b_qrtz_cron_triggers (sched_name varchar) NOT NULL, Trigger_name varchar ($) NOT NULL, Trigger_ Group varchar is not NULL, cron_expression varchar (+) NOT NULL, time_zone_id varchar, primary KEY (Sched_nam E,trigger_name,trigger_group), foreign Key (Sched_name,trigger_name,trigger_group) references T_b_qrtz_triggers (

Sched_name,trigger_name,trigger_group)) Engine=innodb; CREATE TABLE T_b_qrtz_simprop_triggers (sched_name varchar) NOT NULL, Trigger_name varchar ($) NOT NULL, Trigg Er_group varchar (+) NOT NULL, str_prop_1 varchar (512) NULL, str_prop_2 varchar (+) NULL, Str_prop_3 varchar () NULL, int_prop_1 int NULL, int_prop_2 int NULL, long_prop_1 bigint null, long_prop_2 bigint null, dec_prop_1 num Eric (13,4) NULL, dec_prop_2 numeric (13,4) null, BooL_prop_1 varchar (1) NULL, bool_prop_2 varchar (1) NULL, PRIMARY KEY (Sched_name,trigger_name,trigger_group), Foreign
  Key (Sched_name,trigger_name,trigger_group) references t_b_qrtz_triggers (Sched_name,trigger_name,trigger_group))

Engine=innodb; CREATE TABLE T_b_qrtz_blob_triggers (sched_name varchar) NOT NULL, Trigger_name varchar ($) NOT NULL, Trigger_ Group varchar (+) NOT NULL, Blob_data BLOB NULL, PRIMARY KEY (Sched_name,trigger_name,trigger_group), index (sched_ Name,trigger_name, Trigger_group), foreign Key (Sched_name,trigger_name,trigger_group) references T_b_qrtz_triggers (

Sched_name,trigger_name,trigger_group)) Engine=innodb; CREATE TABLE T_b_qrtz_calendars (sched_name varchar) NOT NULL, Calendar_name varchar ($) NOT NULL, calendar bl

OB NOT NULL, primary key (Sched_name,calendar_name)) Engine=innodb; CREATE TABLE T_b_qrtz_paused_trigger_grps (sched_name varchar) NOT NULL, Trigger_group varchar (+) NOT NULL, p Rimary Key (Sched_name,trigger_group)) Engine=innodb;  CREATE TABLE T_b_qrtz_fired_triggers (sched_name varchar) NOT NULL, entry_id varchar (-) NOT NULL, trigger_name varchar () not NULL, Trigger_group varchar ($) NOT NULL, instance_name varchar ($) NOT NULL, fired_time bigint ( Not NULL, sched_time bigint (a) is not NULL, the priority integer is not NULL, the state varchar (+) is not NULL, job_name Varc Har (+) NULL, Job_group varchar ($) NULL, is_nonconcurrent varchar (1) NULL, Requests_recovery varchar (1) NULL, p

Rimary key (sched_name,entry_id)) Engine=innodb; CREATE TABLE T_b_qrtz_scheduler_state (sched_name varchar) NOT NULL, instance_name varchar ($) NOT NULL, Last_ Checkin_time bigint () not NULL, checkin_interval bigint (all) not NULL, primary key (Sched_name,instance_name)) Engi

Ne=innodb; CREATE TABLE T_b_qrtz_locks (sched_name varchar) NOT NULL, Lock_name varchar (+) NOT NULL, PRIMARY key (Sched_n Ame,lock_name)) Engine=innodb;
Create INDEX Idx_qrtz_j_req_recovery on t_b_qrtz_job_details (sched_name,requests_recovery);

Create INDEX IDX_QRTZ_J_GRP on t_b_qrtz_job_details (Sched_name,job_group);
Create INDEX Idx_qrtz_t_j on t_b_qrtz_triggers (Sched_name,job_name,job_group);
Create INDEX IDX_QRTZ_T_JG on t_b_qrtz_triggers (Sched_name,job_group);
Create INDEX Idx_qrtz_t_c on t_b_qrtz_triggers (sched_name,calendar_name);
Create INDEX Idx_qrtz_t_g on t_b_qrtz_triggers (Sched_name,trigger_group);
Create INDEX idx_qrtz_t_state on t_b_qrtz_triggers (sched_name,trigger_state);
Create INDEX idx_qrtz_t_n_state on t_b_qrtz_triggers (sched_name,trigger_name,trigger_group,trigger_state);
Create INDEX idx_qrtz_t_n_g_state on t_b_qrtz_triggers (sched_name,trigger_group,trigger_state);
Create INDEX Idx_qrtz_t_next_fire_time on t_b_qrtz_triggers (sched_name,next_fire_time);
Create INDEX Idx_qrtz_t_nft_st on t_b_qrtz_triggers (sched_name,trigger_state,next_fire_time); Create INDEX Idx_qrtz_t_nft_misfire on t_b_qrtz_triggers (Sched_name,Misfire_instr,next_fire_time); Create INDEX Idx_qrtz_t_nft_st_misfire on t_b_qrtz_triggers (sched_name,misfire_instr,next_fire_time,trigger_state)
; Create INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP on t_b_qrtz_triggers (sched_name,misfire_instr,next_fire_time,trigger_

Group,trigger_state);
Create INDEX Idx_qrtz_ft_trig_inst_name on t_b_qrtz_fired_triggers (sched_name,instance_name); Create INDEX Idx_qrtz_ft_inst_job_req_rcvry on t_b_qrtz_fired_triggers (sched_name,instance_name,requests_recovery)
;
Create INDEX Idx_qrtz_ft_j_g on t_b_qrtz_fired_triggers (Sched_name,job_name,job_group);
Create INDEX IDX_QRTZ_FT_JG on t_b_qrtz_fired_triggers (Sched_name,job_group);
Create INDEX Idx_qrtz_ft_t_g on t_b_qrtz_fired_triggers (Sched_name,trigger_name,trigger_group);

Create INDEX IDX_QRTZ_FT_TG on t_b_qrtz_fired_triggers (Sched_name,trigger_group); Commit
3. application.properties Add cluster configuration in the project
Quartz.scheduler.instancename=cnlmscheduler
Org.quartz.datasource.myds.driver=com.mysql.cj.jdbc.driver
org.quartz.datasource.myds.url=jdbc:mysql://120.77.172.111:3306/touch6?useunicode=true& Characterencoding=utf8
org.quartz.datasource.myds.user=cnlm.me
org.quartz.datasource.myds.password= 123456
org.quartz.datasource.myds.maxconnections=10
4. Scheduling factory configuration Cluster parameters support cluster capability, the following is the scheduling factory class to support cluster capability
Package me.cnlm.springboot.quartz.config;
Import Org.quartz.Trigger;
Import Org.springframework.beans.factory.annotation.Qualifier;
Import Org.springframework.beans.factory.annotation.Value;
Import Org.springframework.context.annotation.Bean;
Import org.springframework.context.annotation.Configuration;

Import Org.springframework.scheduling.quartz.SchedulerFactoryBean;
Import java.io.IOException;

Import java.util.Properties; @Configuration public class Schedulerfactorybeanconfig {@Value ("${quartz.scheduler.instancename}") Private Strin

    G Quartzinstancename;

    @Value ("${org.quartz.datasource.myds.driver}") Private String mydsdriver;

    @Value ("${org.quartz.datasource.myds.url}") Private String Mydsurl;

    @Value ("${org.quartz.datasource.myds.user}") Private String mydsuser;

    @Value ("${org.quartz.datasource.myds.password}") Private String Mydspassword;
@Value ("${org.quartz.datasource.myds.maxconnections}") Private String mydsmaxconnections;

    /** * Scheduled Task cluster configuration * Set Properties * * @return * @throws IOException */Private Properties Quar
        Tzproperties () throws IOException {Properties prop = new Properties ();
        Prop.put ("Quartz.scheduler.instanceName", quartzinstancename);
        Prop.put ("Org.quartz.scheduler.instanceId", "AUTO");
        Prop.put ("Org.quartz.scheduler.skipUpdateCheck", "true");

        Prop.put ("Org.quartz.scheduler.jmx.export", "true");
        Prop.put ("Org.quartz.jobStore.class", "Org.quartz.impl.jdbcjobstore.JobStoreTX");
        Prop.put ("Org.quartz.jobStore.driverDelegateClass", "org.quartz.impl.jdbcjobstore.StdJDBCDelegate");
        Prop.put ("Org.quartz.jobStore.dataSource", "Quartzdatasource");
        Prop.put ("Org.quartz.jobStore.tablePrefix", "t_b_qrtz_");

        Prop.put ("org.quartz.jobStore.isClustered", "true");
        Prop.put ("Org.quartz.jobStore.clusterCheckinInterval", "20000");
      Prop.put ("Org.quartz.jobStore.dataSource", "MyDS");  Prop.put ("Org.quartz.jobStore.maxMisfiresToHandleAtATime", "1");
        Prop.put ("Org.quartz.jobStore.misfireThreshold", "120000");
        Prop.put ("Org.quartz.jobStore.txIsolationLevelSerializable", "true"); Prop.put ("Org.quartz.jobStore.selectWithLockSQL", "select *" from {0}locks WHERE lock_name =?)

        For UPDATE ");
        Prop.put ("Org.quartz.threadPool.class", "Org.quartz.simpl.SimpleThreadPool");
        Prop.put ("Org.quartz.threadPool.threadCount", "10");
        Prop.put ("Org.quartz.threadPool.threadPriority", "5");

        Prop.put ("Org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread", "true");
        Prop.put ("Org.quartz.dataSource.myDS.driver", mydsdriver);
        Prop.put ("Org.quartz.dataSource.myDS.URL", Mydsurl);
        Prop.put ("Org.quartz.dataSource.myDS.user", Mydsuser);
        Prop.put ("Org.quartz.dataSource.myDS.password", Mydspassword);

        Prop.put ("Org.quartz.dataSource.myDS.maxConnections", mydsmaxconnections); PRop.put ("Org.quartz.plugin.triggHistory.class", "Org.quartz.plugins.history.LoggingJobHistoryPlugin");
        Prop.put ("Org.quartz.plugin.shutdownhook.class", "Org.quartz.plugins.management.ShutdownHookPlugin");
        Prop.put ("Org.quartz.plugin.shutdownhook.cleanShutdown", "true");
    return prop;  } @Bean Public Schedulerfactorybean Schedulerfactorybean (@Qualifier ("Sendemailtrigger") Trigger Sendemailtrigger)
        Throws IOException {Schedulerfactorybean factory = new Schedulerfactorybean ();
        Factory.setoverwriteexistingjobs (TRUE);
        For quartz cluster, load quartz data source//factory.setdatasource (DataSource);
Factory.setstartupdelay (10);
        Factory.setquartzproperties (Quartzproperties ());
        Factory.setautostartup (TRUE);
        Factory.setapplicationcontextschedulercontextkey ("ApplicationContext");
        Register trigger Factory.settriggers (Sendemailtrigger);
    return factory; }
}
5. Test verification, slightly (run two project nodes respectively, you can find the above 11 tables added 2 node information and scheduled task running status, which can be verified by itself) This issue is over, so the project supports the scheduled Tasks distributed cluster mode Welcome to join the technical Exchange QQ Group 566654343(rookie Alliance)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.