首页 > 代码库 > 使用sqlserver搭建高可用双机热备的Quartz集群部署【附源码】

使用sqlserver搭建高可用双机热备的Quartz集群部署【附源码】

  一般拿Timer和Quartz相比较的,简直就是对Quartz的侮辱,两者的功能根本就不在一个层级上,如本篇介绍的Quartz强大的集群机制,可以采用基于

sqlserver,mysql的集群方案,当然还可以在第三方插件的基础上实现quartz序列化到热炒的mongodb,redis,震撼力可想而知,接下来本篇就和大家聊

一聊怎么搭建基于sqlserver的quartz集群,实现这么一种双机热备的强大功能。

 

一:下载sqlserver版的建表脚本

    首先大家可以通过github上搜索quartz的源代码,在源码项目的/database/tables目录下,可以找到firebird,oracle,mysql,sqlserver等建库脚本,

本篇只需拿取sqlserver版本即可。 https://github.com/quartznet/quartznet/tree/master/database/tables  如下图所示

 

技术分享

技术分享

 

   

     从上面的截图中可以看到,我接下来要做的事情就是增加一个你需要创建的database名字,这里取为:【quartz】,完整的脚本如下:

技术分享
  1 -- this script is for SQL Server and Azure SQL  2   3 CREATE DATABASE [quartz]  4 GO  5   6 USE [quartz]  7 GO  8   9 IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N[dbo].[FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS]) AND OBJECTPROPERTY(id, NISFOREIGNKEY) = 1) 10 ALTER TABLE [dbo].[QRTZ_TRIGGERS] DROP CONSTRAINT FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS 11 GO 12  13 IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N[dbo].[FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS]) AND OBJECTPROPERTY(id, NISFOREIGNKEY) = 1) 14 ALTER TABLE [dbo].[QRTZ_CRON_TRIGGERS] DROP CONSTRAINT FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS 15 GO 16  17 IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N[dbo].[FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS]) AND OBJECTPROPERTY(id, NISFOREIGNKEY) = 1) 18 ALTER TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] DROP CONSTRAINT FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS 19 GO 20  21 IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N[dbo].[FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS]) AND OBJECTPROPERTY(id, NISFOREIGNKEY) = 1) 22 ALTER TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] DROP CONSTRAINT FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS 23 GO 24  25 IF  EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N[dbo].[FK_QRTZ_JOB_LISTENERS_QRTZ_JOB_DETAILS]) AND parent_object_id = OBJECT_ID(N[dbo].[QRTZ_JOB_LISTENERS])) 26 ALTER TABLE [dbo].[QRTZ_JOB_LISTENERS] DROP CONSTRAINT [FK_QRTZ_JOB_LISTENERS_QRTZ_JOB_DETAILS] 27  28 IF  EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N[dbo].[FK_QRTZ_TRIGGER_LISTENERS_QRTZ_TRIGGERS]) AND parent_object_id = OBJECT_ID(N[dbo].[QRTZ_TRIGGER_LISTENERS])) 29 ALTER TABLE [dbo].[QRTZ_TRIGGER_LISTENERS] DROP CONSTRAINT [FK_QRTZ_TRIGGER_LISTENERS_QRTZ_TRIGGERS] 30  31  32 IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N[dbo].[QRTZ_CALENDARS]) AND OBJECTPROPERTY(id, NISUSERTABLE) = 1) 33 DROP TABLE [dbo].[QRTZ_CALENDARS] 34 GO 35  36 IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N[dbo].[QRTZ_CRON_TRIGGERS]) AND OBJECTPROPERTY(id, NISUSERTABLE) = 1) 37 DROP TABLE [dbo].[QRTZ_CRON_TRIGGERS] 38 GO 39  40 IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N[dbo].[QRTZ_BLOB_TRIGGERS]) AND OBJECTPROPERTY(id, NISUSERTABLE) = 1) 41 DROP TABLE [dbo].[QRTZ_BLOB_TRIGGERS] 42 GO 43  44 IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N[dbo].[QRTZ_FIRED_TRIGGERS]) AND OBJECTPROPERTY(id, NISUSERTABLE) = 1) 45 DROP TABLE [dbo].[QRTZ_FIRED_TRIGGERS] 46 GO 47  48 IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N[dbo].[QRTZ_PAUSED_TRIGGER_GRPS]) AND OBJECTPROPERTY(id, NISUSERTABLE) = 1) 49 DROP TABLE [dbo].[QRTZ_PAUSED_TRIGGER_GRPS] 50 GO 51  52 IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N[dbo].[QRTZ_JOB_LISTENERS]) AND type in (NU)) 53 DROP TABLE [dbo].[QRTZ_JOB_LISTENERS] 54  55 IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N[dbo].[QRTZ_SCHEDULER_STATE]) AND OBJECTPROPERTY(id, NISUSERTABLE) = 1) 56 DROP TABLE [dbo].[QRTZ_SCHEDULER_STATE] 57 GO 58  59 IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N[dbo].[QRTZ_LOCKS]) AND OBJECTPROPERTY(id, NISUSERTABLE) = 1) 60 DROP TABLE [dbo].[QRTZ_LOCKS] 61 GO 62 IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N[dbo].[QRTZ_TRIGGER_LISTENERS]) AND type in (NU)) 63 DROP TABLE [dbo].[QRTZ_TRIGGER_LISTENERS] 64  65  66 IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N[dbo].[QRTZ_JOB_DETAILS]) AND OBJECTPROPERTY(id, NISUSERTABLE) = 1) 67 DROP TABLE [dbo].[QRTZ_JOB_DETAILS] 68 GO 69  70 IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N[dbo].[QRTZ_SIMPLE_TRIGGERS]) AND OBJECTPROPERTY(id, NISUSERTABLE) = 1) 71 DROP TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] 72 GO 73  74 IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N[dbo].[QRTZ_SIMPROP_TRIGGERS]) AND OBJECTPROPERTY(id, NISUSERTABLE) = 1) 75 DROP TABLE [dbo].QRTZ_SIMPROP_TRIGGERS 76 GO 77  78 IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N[dbo].[QRTZ_TRIGGERS]) AND OBJECTPROPERTY(id, NISUSERTABLE) = 1) 79 DROP TABLE [dbo].[QRTZ_TRIGGERS] 80 GO 81  82 CREATE TABLE [dbo].[QRTZ_CALENDARS] ( 83   [SCHED_NAME] [NVARCHAR] (120)  NOT NULL , 84   [CALENDAR_NAME] [NVARCHAR] (200)  NOT NULL , 85   [CALENDAR] [IMAGE] NOT NULL 86 ) 87 GO 88  89 CREATE TABLE [dbo].[QRTZ_CRON_TRIGGERS] ( 90   [SCHED_NAME] [NVARCHAR] (120)  NOT NULL , 91   [TRIGGER_NAME] [NVARCHAR] (150)  NOT NULL , 92   [TRIGGER_GROUP] [NVARCHAR] (150)  NOT NULL , 93   [CRON_EXPRESSION] [NVARCHAR] (120)  NOT NULL , 94   [TIME_ZONE_ID] [NVARCHAR] (80)  95 ) 96 GO 97  98 CREATE TABLE [dbo].[QRTZ_FIRED_TRIGGERS] ( 99   [SCHED_NAME] [NVARCHAR] (120)  NOT NULL ,100   [ENTRY_ID] [NVARCHAR] (140)  NOT NULL ,101   [TRIGGER_NAME] [NVARCHAR] (150)  NOT NULL ,102   [TRIGGER_GROUP] [NVARCHAR] (150)  NOT NULL ,103   [INSTANCE_NAME] [NVARCHAR] (200)  NOT NULL ,104   [FIRED_TIME] [BIGINT] NOT NULL ,105   [SCHED_TIME] [BIGINT] NOT NULL ,106   [PRIORITY] [INTEGER] NOT NULL ,107   [STATE] [NVARCHAR] (16)  NOT NULL,108   [JOB_NAME] [NVARCHAR] (150)  NULL ,109   [JOB_GROUP] [NVARCHAR] (150)  NULL ,110   [IS_NONCONCURRENT] BIT  NULL ,111   [REQUESTS_RECOVERY] BIT  NULL 112 )113 GO114 115 CREATE TABLE [dbo].[QRTZ_PAUSED_TRIGGER_GRPS] (116   [SCHED_NAME] [NVARCHAR] (120)  NOT NULL ,117   [TRIGGER_GROUP] [NVARCHAR] (150)  NOT NULL 118 )119 GO120 121 CREATE TABLE [dbo].[QRTZ_SCHEDULER_STATE] (122   [SCHED_NAME] [NVARCHAR] (120)  NOT NULL ,123   [INSTANCE_NAME] [NVARCHAR] (200)  NOT NULL ,124   [LAST_CHECKIN_TIME] [BIGINT] NOT NULL ,125   [CHECKIN_INTERVAL] [BIGINT] NOT NULL126 )127 GO128 129 CREATE TABLE [dbo].[QRTZ_LOCKS] (130   [SCHED_NAME] [NVARCHAR] (120)  NOT NULL ,131   [LOCK_NAME] [NVARCHAR] (40)  NOT NULL 132 )133 GO134 135 CREATE TABLE [dbo].[QRTZ_JOB_DETAILS] (136   [SCHED_NAME] [NVARCHAR] (120)  NOT NULL ,137   [JOB_NAME] [NVARCHAR] (150)  NOT NULL ,138   [JOB_GROUP] [NVARCHAR] (150)  NOT NULL ,139   [DESCRIPTION] [NVARCHAR] (250) NULL ,140   [JOB_CLASS_NAME] [NVARCHAR] (250)  NOT NULL ,141   [IS_DURABLE] BIT  NOT NULL ,142   [IS_NONCONCURRENT] BIT  NOT NULL ,143   [IS_UPDATE_DATA] BIT  NOT NULL ,144   [REQUESTS_RECOVERY] BIT  NOT NULL ,145   [JOB_DATA] [IMAGE] NULL146 )147 GO148 149 CREATE TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] (150   [SCHED_NAME] [NVARCHAR] (120)  NOT NULL ,151   [TRIGGER_NAME] [NVARCHAR] (150)  NOT NULL ,152   [TRIGGER_GROUP] [NVARCHAR] (150)  NOT NULL ,153   [REPEAT_COUNT] [INTEGER] NOT NULL ,154   [REPEAT_INTERVAL] [BIGINT] NOT NULL ,155   [TIMES_TRIGGERED] [INTEGER] NOT NULL156 )157 GO158 159 CREATE TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] (160   [SCHED_NAME] [NVARCHAR] (120)  NOT NULL ,161   [TRIGGER_NAME] [NVARCHAR] (150)  NOT NULL ,162   [TRIGGER_GROUP] [NVARCHAR] (150)  NOT NULL ,163   [STR_PROP_1] [NVARCHAR] (512) NULL,164   [STR_PROP_2] [NVARCHAR] (512) NULL,165   [STR_PROP_3] [NVARCHAR] (512) NULL,166   [INT_PROP_1] [INT] NULL,167   [INT_PROP_2] [INT] NULL,168   [LONG_PROP_1] [BIGINT] NULL,169   [LONG_PROP_2] [BIGINT] NULL,170   [DEC_PROP_1] [NUMERIC] (13,4) NULL,171   [DEC_PROP_2] [NUMERIC] (13,4) NULL,172   [BOOL_PROP_1] BIT NULL,173   [BOOL_PROP_2] BIT NULL,174 )175 GO176 177 CREATE TABLE [dbo].[QRTZ_BLOB_TRIGGERS] (178   [SCHED_NAME] [NVARCHAR] (120)  NOT NULL ,179   [TRIGGER_NAME] [NVARCHAR] (150)  NOT NULL ,180   [TRIGGER_GROUP] [NVARCHAR] (150)  NOT NULL ,181   [BLOB_DATA] [IMAGE] NULL182 )183 GO184 185 CREATE TABLE [dbo].[QRTZ_TRIGGERS] (186   [SCHED_NAME] [NVARCHAR] (120)  NOT NULL ,187   [TRIGGER_NAME] [NVARCHAR] (150)  NOT NULL ,188   [TRIGGER_GROUP] [NVARCHAR] (150)  NOT NULL ,189   [JOB_NAME] [NVARCHAR] (150)  NOT NULL ,190   [JOB_GROUP] [NVARCHAR] (150)  NOT NULL ,191   [DESCRIPTION] [NVARCHAR] (250) NULL ,192   [NEXT_FIRE_TIME] [BIGINT] NULL ,193   [PREV_FIRE_TIME] [BIGINT] NULL ,194   [PRIORITY] [INTEGER] NULL ,195   [TRIGGER_STATE] [NVARCHAR] (16)  NOT NULL ,196   [TRIGGER_TYPE] [NVARCHAR] (8)  NOT NULL ,197   [START_TIME] [BIGINT] NOT NULL ,198   [END_TIME] [BIGINT] NULL ,199   [CALENDAR_NAME] [NVARCHAR] (200)  NULL ,200   [MISFIRE_INSTR] [INTEGER] NULL ,201   [JOB_DATA] [IMAGE] NULL202 )203 GO204 205 ALTER TABLE [dbo].[QRTZ_CALENDARS] WITH NOCHECK ADD206   CONSTRAINT [PK_QRTZ_CALENDARS] PRIMARY KEY  CLUSTERED207   (208     [SCHED_NAME],209     [CALENDAR_NAME]210   ) 211 GO212 213 ALTER TABLE [dbo].[QRTZ_CRON_TRIGGERS] WITH NOCHECK ADD214   CONSTRAINT [PK_QRTZ_CRON_TRIGGERS] PRIMARY KEY  CLUSTERED215   (216     [SCHED_NAME],217     [TRIGGER_NAME],218     [TRIGGER_GROUP]219   ) 220 GO221 222 ALTER TABLE [dbo].[QRTZ_FIRED_TRIGGERS] WITH NOCHECK ADD223   CONSTRAINT [PK_QRTZ_FIRED_TRIGGERS] PRIMARY KEY  CLUSTERED224   (225     [SCHED_NAME],226     [ENTRY_ID]227   ) 228 GO229 230 ALTER TABLE [dbo].[QRTZ_PAUSED_TRIGGER_GRPS] WITH NOCHECK ADD231   CONSTRAINT [PK_QRTZ_PAUSED_TRIGGER_GRPS] PRIMARY KEY  CLUSTERED232   (233     [SCHED_NAME],234     [TRIGGER_GROUP]235   ) 236 GO237 238 ALTER TABLE [dbo].[QRTZ_SCHEDULER_STATE] WITH NOCHECK ADD239   CONSTRAINT [PK_QRTZ_SCHEDULER_STATE] PRIMARY KEY  CLUSTERED240   (241     [SCHED_NAME],242     [INSTANCE_NAME]243   ) 244 GO245 246 ALTER TABLE [dbo].[QRTZ_LOCKS] WITH NOCHECK ADD247   CONSTRAINT [PK_QRTZ_LOCKS] PRIMARY KEY  CLUSTERED248   (249     [SCHED_NAME],250     [LOCK_NAME]251   ) 252 GO253 254 ALTER TABLE [dbo].[QRTZ_JOB_DETAILS] WITH NOCHECK ADD255   CONSTRAINT [PK_QRTZ_JOB_DETAILS] PRIMARY KEY  CLUSTERED256   (257     [SCHED_NAME],258     [JOB_NAME],259     [JOB_GROUP]260   ) 261 GO262 263 ALTER TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] WITH NOCHECK ADD264   CONSTRAINT [PK_QRTZ_SIMPLE_TRIGGERS] PRIMARY KEY  CLUSTERED265   (266     [SCHED_NAME],267     [TRIGGER_NAME],268     [TRIGGER_GROUP]269   ) 270 GO271 272 ALTER TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] WITH NOCHECK ADD273   CONSTRAINT [PK_QRTZ_SIMPROP_TRIGGERS] PRIMARY KEY  CLUSTERED274   (275     [SCHED_NAME],276     [TRIGGER_NAME],277     [TRIGGER_GROUP]278   ) 279 GO280 281 ALTER TABLE [dbo].[QRTZ_TRIGGERS] WITH NOCHECK ADD282   CONSTRAINT [PK_QRTZ_TRIGGERS] PRIMARY KEY  CLUSTERED283   (284     [SCHED_NAME],285     [TRIGGER_NAME],286     [TRIGGER_GROUP]287   ) 288 GO289 290 ALTER TABLE [dbo].QRTZ_BLOB_TRIGGERS WITH NOCHECK ADD291   CONSTRAINT [PK_QRTZ_BLOB_TRIGGERS] PRIMARY KEY  CLUSTERED292   (293     [SCHED_NAME],294     [TRIGGER_NAME],295     [TRIGGER_GROUP]296   ) 297 GO298 299 ALTER TABLE [dbo].[QRTZ_CRON_TRIGGERS] ADD300   CONSTRAINT [FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY301   (302     [SCHED_NAME],303     [TRIGGER_NAME],304     [TRIGGER_GROUP]305   ) REFERENCES [dbo].[QRTZ_TRIGGERS] (306     [SCHED_NAME],307     [TRIGGER_NAME],308     [TRIGGER_GROUP]309   ) ON DELETE CASCADE310 GO311 312 ALTER TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] ADD313   CONSTRAINT [FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY314   (315     [SCHED_NAME],316     [TRIGGER_NAME],317     [TRIGGER_GROUP]318   ) REFERENCES [dbo].[QRTZ_TRIGGERS] (319     [SCHED_NAME],320     [TRIGGER_NAME],321     [TRIGGER_GROUP]322   ) ON DELETE CASCADE323 GO324 325 ALTER TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] ADD326   CONSTRAINT [FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY327   (328     [SCHED_NAME],329     [TRIGGER_NAME],330     [TRIGGER_GROUP]331   ) REFERENCES [dbo].[QRTZ_TRIGGERS] (332     [SCHED_NAME],333     [TRIGGER_NAME],334     [TRIGGER_GROUP]335   ) ON DELETE CASCADE336 GO337 338 ALTER TABLE [dbo].[QRTZ_TRIGGERS] ADD339   CONSTRAINT [FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS] FOREIGN KEY340   (341     [SCHED_NAME],342     [JOB_NAME],343     [JOB_GROUP]344   ) REFERENCES [dbo].[QRTZ_JOB_DETAILS] (345     [SCHED_NAME],346     [JOB_NAME],347     [JOB_GROUP]348   )349 GO350 351 CREATE INDEX IDX_QRTZ_T_J ON QRTZ_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP)352 CREATE INDEX IDX_QRTZ_T_JG ON QRTZ_TRIGGERS(SCHED_NAME,JOB_GROUP)353 CREATE INDEX IDX_QRTZ_T_C ON QRTZ_TRIGGERS(SCHED_NAME,CALENDAR_NAME)354 CREATE INDEX IDX_QRTZ_T_G ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP)355 CREATE INDEX IDX_QRTZ_T_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE)356 CREATE INDEX IDX_QRTZ_T_N_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE)357 CREATE INDEX IDX_QRTZ_T_N_G_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE)358 CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME ON QRTZ_TRIGGERS(SCHED_NAME,NEXT_FIRE_TIME)359 CREATE INDEX IDX_QRTZ_T_NFT_ST ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME)360 CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME)361 CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE)362 CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE)363 364 CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME)365 CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY)366 CREATE INDEX IDX_QRTZ_FT_J_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP)367 CREATE INDEX IDX_QRTZ_FT_JG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_GROUP)368 CREATE INDEX IDX_QRTZ_FT_T_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)369 CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP)370 GO
View Code

 

技术分享

 

二:配置quartz的集群参数

    当我们写var scheduler = StdSchedulerFactory.GetDefaultScheduler()这段代码的时候,如果大家看过源码的话,会知道这个GetScheduler的

过程中有一个初始化方法【Instantiate】方法,此方法中你会发现在做DBProvider的时候会需要几个参数来初始化DB的,比如下面看到的几个标红属性。

 1             IList<string> dsNames = cfg.GetPropertyGroups(PropertyDataSourcePrefix); 2             foreach (string dataSourceName in dsNames) 3             { 4                 string datasourceKey = "{0}.{1}".FormatInvariant(PropertyDataSourcePrefix, dataSourceName); 5                 NameValueCollection propertyGroup = cfg.GetPropertyGroup(datasourceKey, true); 6                 PropertiesParser pp = new PropertiesParser(propertyGroup); 7  8                 Type cpType = loadHelper.LoadType(pp.GetStringProperty(PropertyDbProviderType, null)); 9 10                 // custom connectionProvider...11                 if (cpType != null)12                 {13                     IDbProvider cp;14                     try15                     {16                         cp = ObjectUtils.InstantiateType<IDbProvider>(cpType);17                     }18                     catch (Exception e)19                     {20                         initException = new SchedulerException("ConnectionProvider of type ‘{0}‘ could not be instantiated.".FormatInvariant(cpType), e);21                         throw initException;22                     }23 24                     try25                     {26                         // remove the type name, so it isn‘t attempted to be set27                         pp.UnderlyingProperties.Remove(PropertyDbProviderType);28 29                         ObjectUtils.SetObjectProperties(cp, pp.UnderlyingProperties);30                         cp.Initialize();31                     }32                     catch (Exception e)33                     {34                         initException = new SchedulerException("ConnectionProvider type ‘{0}‘ props could not be configured.".FormatInvariant(cpType), e);35                         throw initException;36                     }37 38                     dbMgr = DBConnectionManager.Instance;39                     dbMgr.AddConnectionProvider(dataSourceName, cp);40                 }41                 else42                 {43                     string dsProvider = pp.GetStringProperty(PropertyDataSourceProvider, null);44                     string dsConnectionString = pp.GetStringProperty(PropertyDataSourceConnectionString, null);45                     string dsConnectionStringName = pp.GetStringProperty(PropertyDataSourceConnectionStringName, null);46 47                     if (dsConnectionString == null && !String.IsNullOrEmpty(dsConnectionStringName))48                     {49 50                         ConnectionStringSettings connectionStringSettings = ConfigurationManager.ConnectionStrings[dsConnectionStringName];51                         if (connectionStringSettings == null)52                         {53                             initException = new SchedulerException("Named connection string ‘{0}‘ not found for DataSource: {1}".FormatInvariant(dsConnectionStringName, dataSourceName));54                             throw initException;55                         }56                         dsConnectionString = connectionStringSettings.ConnectionString;57                     }58 59                     if (dsProvider == null)60                     {61                         initException = new SchedulerException("Provider not specified for DataSource: {0}".FormatInvariant(dataSourceName));62                         throw initException;63                     }64                     if (dsConnectionString == null)65                     {66                         initException = new SchedulerException("Connection string not specified for DataSource: {0}".FormatInvariant(dataSourceName));67                         throw initException;68                     }69                     try70                     {71                         DbProvider dbp = new DbProvider(dsProvider, dsConnectionString);72                         dbp.Initialize();73 74                         dbMgr = DBConnectionManager.Instance;75                         dbMgr.AddConnectionProvider(dataSourceName, dbp);76                     }77                     catch (Exception exception)78                     {79                         initException = new SchedulerException("Could not Initialize DataSource: {0}".FormatInvariant(dataSourceName), exception);80                         throw initException;81                     }82                 }83             }

 

     接下来的问题就是这几个属性是如何配置进去的,仔细观察上面代码,你会发现所有的配置的源头都来自于cfg变量,ok,接下来你可以继续翻看代码,相信

你会看到有一个Initialize方法就是做cfg变量的初始化,如下代码所示:

 1   public void Initialize() 2         { 3             // short-circuit if already initialized 4             if (cfg != null) 5             { 6                 return; 7             } 8             if (initException != null) 9             {10                 throw initException;11             }12 13             NameValueCollection props = (NameValueCollection) ConfigurationManager.GetSection(ConfigurationSectionName);14 15             string requestedFile = QuartzEnvironment.GetEnvironmentVariable(PropertiesFile);16 17             string propFileName = requestedFile != null && requestedFile.Trim().Length > 0 ? requestedFile : "~/quartz.config";18 19             // check for specials20             try21             {22                 propFileName = FileUtil.ResolveFile(propFileName);23             }24             catch (SecurityException)25             {26                 log.WarnFormat("Unable to resolve file path ‘{0}‘ due to security exception, probably running under medium trust");27                 propFileName = "quartz.config";28             }29 30             if (props == null && File.Exists(propFileName))31             {32                 // file system33                 try34                 {35                     PropertiesParser pp = PropertiesParser.ReadFromFileResource(propFileName);36                     props = pp.UnderlyingProperties;37                     Log.Info(string.Format("Quartz.NET properties loaded from configuration file ‘{0}‘", propFileName));38                 }39                 catch (Exception ex)40                 {41                     Log.Error("Could not load properties for Quartz from file {0}: {1}".FormatInvariant(propFileName, ex.Message), ex);42                 }43 44             }45             if (props == null)46             {47                 // read from assembly48                 try49                 {50                     PropertiesParser pp = PropertiesParser.ReadFromEmbeddedAssemblyResource("Quartz.quartz.config");51                     props = pp.UnderlyingProperties;52                     Log.Info("Default Quartz.NET properties loaded from embedded resource file");53                 }54                 catch (Exception ex)55                 {56                     Log.Error("Could not load default properties for Quartz from Quartz assembly: {0}".FormatInvariant(ex.Message), ex);57                 }58             }59             if (props == null)60             {61                 throw new SchedulerConfigException(62                     @"Could not find <quartz> configuration section from your application config or load default configuration from assembly.63 Please add configuration to your application config file to correctly initialize Quartz.");64             }65             Initialize(OverrideWithSysProps(props));66         }

     

     仔细阅读上面的一串代码,你会发现,默认quartz参数配置来源于三个地方。

1. app.config中的section节点。

2. bin目录下的~/quartz.config文件。

3. 默认配置的NameValueCollection字典集合,也就是上一篇博客给大家做的一个演示。

   

     我个人不怎么喜欢通过quartz.config文件进行配置,这样也容易写死,所以我还是喜欢使用最简单的NameValueCollection配置,因为它的数据源可来源

于第三方存储结构中,配置代码如下:

 1                 //1.首先创建一个作业调度池 2                 var properties = new NameValueCollection(); 3                 //存储类型 4                 properties["quartz.jobStore.type"] = "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz"; 5  6                 //驱动类型 7                 properties["quartz.jobStore.driverDelegateType"] = "Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz";                //数据源名称 8                 properties["quartz.jobStore.dataSource"] = "myDS"; 9 10                 //连接字符串11                 properties["quartz.dataSource.myDS.connectionString"] = @"server=.;Initial Catalog=quartz;Integrated Security=True";12                 //sqlserver版本13                 properties["quartz.dataSource.myDS.provider"] = "SqlServer-20";14 15                 //是否集群16                 properties["quartz.jobStore.clustered"] = "true";17                 properties["quartz.scheduler.instanceId"] = "AUTO";

 

    上面的代码配置我都加过详细的注释,大家应该都能看得懂,而且这些配置就是这么定死的,没什么修改的空间,大家记住即可。

 

三:Job和Trigger定义

     在集群中环境下,job和trigger的定义该怎么写的?大家也不要想的太复杂,注意一点就可以了,在Schedule一个Job时候,通过CheckExists判断一下

这个Job在Scheduler中是否已经存在了,如果存在,你就不能再次通过Schedule去重复调度一个Job就可以了。。。所以判断的代码也很简单,如下所示:

 1          IScheduler scheduler = factory.GetScheduler(); 2  3                 scheduler.Start(); 4  5                 var jobKey = JobKey.Create("myjob", "group"); 6  7                 if (scheduler.CheckExists(jobKey)) 8                 { 9                     Console.WriteLine("当前job已经存在,无需调度:{0}", jobKey.ToString());10                 }11                 else12                 {13                     IJobDetail job = JobBuilder.Create<HelloJob>()14                            .WithDescription("使用quartz进行持久化存储")15                            .StoreDurably()16                            .RequestRecovery()17                            .WithIdentity(jobKey)18                            .UsingJobData("count", 1)19                            .Build();20 21                     ITrigger trigger = TriggerBuilder.Create().WithSimpleSchedule(x => x.WithIntervalInSeconds(2).RepeatForever())22                                                               .Build();23 24                     scheduler.ScheduleJob(job, trigger);25 26                     Console.WriteLine("调度进行中!!!");27                 }

 

上面这段代码,大家就可以部署在多台机器中了,是不是很简单?

 

四:强大的cluster完整演示

   

     所有的初始化工作都做完了,接下来我们copy一份bin文件,同时打开两个console程序,如下所示,可以看到job任务只会被一个console调度,另外

一个在空等待。

技术分享

 

       然后你肯定很好奇的跑到sqlserver中去看看,是否已经有job和trigger的db存储,很开心吧,数据都有的。。。

技术分享

 

       好了,一切都是那么完美,接下来可以展示一下quartz集群下的高可用啦,如果某一个console挂了,那么另一台console会把这个任务给接过来,实

现强大的高可用。。。所以我要做的事情就是把console1关掉,再看看console2是不是可以开始调度job了???

技术分享

 

完美,这个就是本篇给大家介绍的Quartz的Cluster集群,一台挂,另一台顶住,双击热备,当然这些console你可以部署在多台机器中,要做的就是保持各

个server的时间同步,因为quarz是依赖于本机server的时间,好了,本篇就先说到这里吧。

 

小礼物走一波,双击666。。。  完整代码:QuartzCluster.zip

 

使用sqlserver搭建高可用双机热备的Quartz集群部署【附源码】