通常拿Timer和Quartz相比較的,簡直就是對Quartz的侮辱,二者的功能根本就不在一個層級上,如本篇介紹的Quartz強大的集羣機制,能夠採用基於mysql
sqlserver,mysql的集羣方案,固然還能夠在第三方插件的基礎上實現quartz序列化到熱炒的mongodb,redis,震撼力可想而知,接下來本篇就和你們聊git
一聊怎麼搭建基於sqlserver的quartz集羣,實現這麼一種雙機熱備的強大功能。github
一:下載sqlserver版的建表腳本redis
首先你們能夠經過github上搜索quartz的源代碼,在源碼項目的/database/tables目錄下,能夠找到firebird,oracle,mysql,sqlserver等建庫腳本,sql
本篇只需拿取sqlserver版本便可。 https://github.com/quartznet/quartznet/tree/master/database/tables 以下圖所示mongodb
從上面的截圖中能夠看到,我接下來要作的事情就是增長一個你須要建立的database名字,這裏取爲:【quartz】,完整的腳本以下:oracle
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, N'ISFOREIGNKEY') = 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, N'ISFOREIGNKEY') = 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, N'ISFOREIGNKEY') = 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, N'ISFOREIGNKEY') = 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, N'ISUSERTABLE') = 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, N'ISUSERTABLE') = 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, N'ISUSERTABLE') = 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, N'ISUSERTABLE') = 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, N'ISUSERTABLE') = 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 (N'U')) 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, N'ISUSERTABLE') = 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, N'ISUSERTABLE') = 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 (N'U')) 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, N'ISUSERTABLE') = 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, N'ISUSERTABLE') = 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, N'ISUSERTABLE') = 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, N'ISUSERTABLE') = 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 GO 114 115 CREATE TABLE [dbo].[QRTZ_PAUSED_TRIGGER_GRPS] ( 116 [SCHED_NAME] [NVARCHAR] (120) NOT NULL , 117 [TRIGGER_GROUP] [NVARCHAR] (150) NOT NULL 118 ) 119 GO 120 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 NULL 126 ) 127 GO 128 129 CREATE TABLE [dbo].[QRTZ_LOCKS] ( 130 [SCHED_NAME] [NVARCHAR] (120) NOT NULL , 131 [LOCK_NAME] [NVARCHAR] (40) NOT NULL 132 ) 133 GO 134 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] NULL 146 ) 147 GO 148 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 NULL 156 ) 157 GO 158 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 GO 176 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] NULL 182 ) 183 GO 184 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] NULL 202 ) 203 GO 204 205 ALTER TABLE [dbo].[QRTZ_CALENDARS] WITH NOCHECK ADD 206 CONSTRAINT [PK_QRTZ_CALENDARS] PRIMARY KEY CLUSTERED 207 ( 208 [SCHED_NAME], 209 [CALENDAR_NAME] 210 ) 211 GO 212 213 ALTER TABLE [dbo].[QRTZ_CRON_TRIGGERS] WITH NOCHECK ADD 214 CONSTRAINT [PK_QRTZ_CRON_TRIGGERS] PRIMARY KEY CLUSTERED 215 ( 216 [SCHED_NAME], 217 [TRIGGER_NAME], 218 [TRIGGER_GROUP] 219 ) 220 GO 221 222 ALTER TABLE [dbo].[QRTZ_FIRED_TRIGGERS] WITH NOCHECK ADD 223 CONSTRAINT [PK_QRTZ_FIRED_TRIGGERS] PRIMARY KEY CLUSTERED 224 ( 225 [SCHED_NAME], 226 [ENTRY_ID] 227 ) 228 GO 229 230 ALTER TABLE [dbo].[QRTZ_PAUSED_TRIGGER_GRPS] WITH NOCHECK ADD 231 CONSTRAINT [PK_QRTZ_PAUSED_TRIGGER_GRPS] PRIMARY KEY CLUSTERED 232 ( 233 [SCHED_NAME], 234 [TRIGGER_GROUP] 235 ) 236 GO 237 238 ALTER TABLE [dbo].[QRTZ_SCHEDULER_STATE] WITH NOCHECK ADD 239 CONSTRAINT [PK_QRTZ_SCHEDULER_STATE] PRIMARY KEY CLUSTERED 240 ( 241 [SCHED_NAME], 242 [INSTANCE_NAME] 243 ) 244 GO 245 246 ALTER TABLE [dbo].[QRTZ_LOCKS] WITH NOCHECK ADD 247 CONSTRAINT [PK_QRTZ_LOCKS] PRIMARY KEY CLUSTERED 248 ( 249 [SCHED_NAME], 250 [LOCK_NAME] 251 ) 252 GO 253 254 ALTER TABLE [dbo].[QRTZ_JOB_DETAILS] WITH NOCHECK ADD 255 CONSTRAINT [PK_QRTZ_JOB_DETAILS] PRIMARY KEY CLUSTERED 256 ( 257 [SCHED_NAME], 258 [JOB_NAME], 259 [JOB_GROUP] 260 ) 261 GO 262 263 ALTER TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] WITH NOCHECK ADD 264 CONSTRAINT [PK_QRTZ_SIMPLE_TRIGGERS] PRIMARY KEY CLUSTERED 265 ( 266 [SCHED_NAME], 267 [TRIGGER_NAME], 268 [TRIGGER_GROUP] 269 ) 270 GO 271 272 ALTER TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] WITH NOCHECK ADD 273 CONSTRAINT [PK_QRTZ_SIMPROP_TRIGGERS] PRIMARY KEY CLUSTERED 274 ( 275 [SCHED_NAME], 276 [TRIGGER_NAME], 277 [TRIGGER_GROUP] 278 ) 279 GO 280 281 ALTER TABLE [dbo].[QRTZ_TRIGGERS] WITH NOCHECK ADD 282 CONSTRAINT [PK_QRTZ_TRIGGERS] PRIMARY KEY CLUSTERED 283 ( 284 [SCHED_NAME], 285 [TRIGGER_NAME], 286 [TRIGGER_GROUP] 287 ) 288 GO 289 290 ALTER TABLE [dbo].QRTZ_BLOB_TRIGGERS WITH NOCHECK ADD 291 CONSTRAINT [PK_QRTZ_BLOB_TRIGGERS] PRIMARY KEY CLUSTERED 292 ( 293 [SCHED_NAME], 294 [TRIGGER_NAME], 295 [TRIGGER_GROUP] 296 ) 297 GO 298 299 ALTER TABLE [dbo].[QRTZ_CRON_TRIGGERS] ADD 300 CONSTRAINT [FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY 301 ( 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 CASCADE 310 GO 311 312 ALTER TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] ADD 313 CONSTRAINT [FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY 314 ( 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 CASCADE 323 GO 324 325 ALTER TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] ADD 326 CONSTRAINT [FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY 327 ( 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 CASCADE 336 GO 337 338 ALTER TABLE [dbo].[QRTZ_TRIGGERS] ADD 339 CONSTRAINT [FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS] FOREIGN KEY 340 ( 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 GO 350 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
二:配置quartz的集羣參數app
當咱們寫var scheduler = StdSchedulerFactory.GetDefaultScheduler()這段代碼的時候,若是你們看過源碼的話,會知道這個GetScheduler的ide
過程當中有一個初始化方法【Instantiate】方法,此方法中你會發如今作DBProvider的時候會須要幾個參數來初始化DB的,好比下面看到的幾個標紅屬性。sqlserver
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 try 15 { 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 try 25 { 26 // remove the type name, so it isn't attempted to be set 27 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 else 42 { 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 try 70 { 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 specials 20 try 21 { 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 system 33 try 34 { 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 assembly 48 try 49 { 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 else 12 { 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。。。 完整代碼:SimpleSchedulerApp.zip