接触Quartznet之前,老东家用的是总监自己写的分布式任务框架,好用但是配置麻烦,unity,一个微软容器,配置节点错一个,整个使用到unity文件的项目全部跑不起来,这后果真的受不了。。。
目前公司呢,没什么框架,全都是自己研究,自己找,合适的就用,独立自主,可是这样的方式真的好么,一个员工离职,或许他引进的东西别人要推翻重写,代价也不小。。算了还是说下自己用到的东西吧。这里只是简单记录,有问题可以私信。
1.新建控制台项目,这里就叫DistributedService;
2.通过NuGet包管理器,或者命令行,添加Topshelf,Quartz;
3.既然分布式集群,多机热备,就采用官方的SQL Server持久化存储,sql脚本地址:https://github.com/quartznet/quartznet/tree/master/database
具体脚本内容
1 USE 数据库名 2 GO 3 4 IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N‘[dbo].[FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS]‘) AND OBJECTPROPERTY(id, N‘ISFOREIGNKEY‘) = 1) 5 ALTER TABLE [dbo].[QRTZ_TRIGGERS] DROP CONSTRAINT FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS 6 GO 7 8 IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N‘[dbo].[FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS]‘) AND OBJECTPROPERTY(id, N‘ISFOREIGNKEY‘) = 1) 9 ALTER TABLE [dbo].[QRTZ_CRON_TRIGGERS] DROP CONSTRAINT FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS 10 GO 11 12 IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N‘[dbo].[FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS]‘) AND OBJECTPROPERTY(id, N‘ISFOREIGNKEY‘) = 1) 13 ALTER TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] DROP CONSTRAINT FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS 14 GO 15 16 IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N‘[dbo].[FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS]‘) AND OBJECTPROPERTY(id, N‘ISFOREIGNKEY‘) = 1) 17 ALTER TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] DROP CONSTRAINT FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS 18 GO 19 20 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]‘)) 21 ALTER TABLE [dbo].[QRTZ_JOB_LISTENERS] DROP CONSTRAINT [FK_QRTZ_JOB_LISTENERS_QRTZ_JOB_DETAILS] 22 23 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]‘)) 24 ALTER TABLE [dbo].[QRTZ_TRIGGER_LISTENERS] DROP CONSTRAINT [FK_QRTZ_TRIGGER_LISTENERS_QRTZ_TRIGGERS] 25 26 27 IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N‘[dbo].[QRTZ_CALENDARS]‘) AND OBJECTPROPERTY(id, N‘ISUSERTABLE‘) = 1) 28 DROP TABLE [dbo].[QRTZ_CALENDARS] 29 GO 30 31 IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N‘[dbo].[QRTZ_CRON_TRIGGERS]‘) AND OBJECTPROPERTY(id, N‘ISUSERTABLE‘) = 1) 32 DROP TABLE [dbo].[QRTZ_CRON_TRIGGERS] 33 GO 34 35 IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N‘[dbo].[QRTZ_BLOB_TRIGGERS]‘) AND OBJECTPROPERTY(id, N‘ISUSERTABLE‘) = 1) 36 DROP TABLE [dbo].[QRTZ_BLOB_TRIGGERS] 37 GO 38 39 IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N‘[dbo].[QRTZ_FIRED_TRIGGERS]‘) AND OBJECTPROPERTY(id, N‘ISUSERTABLE‘) = 1) 40 DROP TABLE [dbo].[QRTZ_FIRED_TRIGGERS] 41 GO 42 43 IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N‘[dbo].[QRTZ_PAUSED_TRIGGER_GRPS]‘) AND OBJECTPROPERTY(id, N‘ISUSERTABLE‘) = 1) 44 DROP TABLE [dbo].[QRTZ_PAUSED_TRIGGER_GRPS] 45 GO 46 47 IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N‘[dbo].[QRTZ_JOB_LISTENERS]‘) AND type in (N‘U‘)) 48 DROP TABLE [dbo].[QRTZ_JOB_LISTENERS] 49 50 IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N‘[dbo].[QRTZ_SCHEDULER_STATE]‘) AND OBJECTPROPERTY(id, N‘ISUSERTABLE‘) = 1) 51 DROP TABLE [dbo].[QRTZ_SCHEDULER_STATE] 52 GO 53 54 IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N‘[dbo].[QRTZ_LOCKS]‘) AND OBJECTPROPERTY(id, N‘ISUSERTABLE‘) = 1) 55 DROP TABLE [dbo].[QRTZ_LOCKS] 56 GO 57 IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N‘[dbo].[QRTZ_TRIGGER_LISTENERS]‘) AND type in (N‘U‘)) 58 DROP TABLE [dbo].[QRTZ_TRIGGER_LISTENERS] 59 60 61 IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N‘[dbo].[QRTZ_JOB_DETAILS]‘) AND OBJECTPROPERTY(id, N‘ISUSERTABLE‘) = 1) 62 DROP TABLE [dbo].[QRTZ_JOB_DETAILS] 63 GO 64 65 IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N‘[dbo].[QRTZ_SIMPLE_TRIGGERS]‘) AND OBJECTPROPERTY(id, N‘ISUSERTABLE‘) = 1) 66 DROP TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] 67 GO 68 69 IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N‘[dbo].[QRTZ_SIMPROP_TRIGGERS]‘) AND OBJECTPROPERTY(id, N‘ISUSERTABLE‘) = 1) 70 DROP TABLE [dbo].QRTZ_SIMPROP_TRIGGERS 71 GO 72 73 IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N‘[dbo].[QRTZ_TRIGGERS]‘) AND OBJECTPROPERTY(id, N‘ISUSERTABLE‘) = 1) 74 DROP TABLE [dbo].[QRTZ_TRIGGERS] 75 GO 76 77 CREATE TABLE [dbo].[QRTZ_CALENDARS] ( 78 [SCHED_NAME] [NVARCHAR] (120) NOT NULL , 79 [CALENDAR_NAME] [NVARCHAR] (200) NOT NULL , 80 [CALENDAR] [IMAGE] NOT NULL 81 ) 82 GO 83 84 CREATE TABLE [dbo].[QRTZ_CRON_TRIGGERS] ( 85 [SCHED_NAME] [NVARCHAR] (120) NOT NULL , 86 [TRIGGER_NAME] [NVARCHAR] (150) NOT NULL , 87 [TRIGGER_GROUP] [NVARCHAR] (150) NOT NULL , 88 [CRON_EXPRESSION] [NVARCHAR] (120) NOT NULL , 89 [TIME_ZONE_ID] [NVARCHAR] (80) 90 ) 91 GO 92 93 CREATE TABLE [dbo].[QRTZ_FIRED_TRIGGERS] ( 94 [SCHED_NAME] [NVARCHAR] (120) NOT NULL , 95 [ENTRY_ID] [NVARCHAR] (140) NOT NULL , 96 [TRIGGER_NAME] [NVARCHAR] (150) NOT NULL , 97 [TRIGGER_GROUP] [NVARCHAR] (150) NOT NULL , 98 [INSTANCE_NAME] [NVARCHAR] (200) NOT NULL , 99 [FIRED_TIME] [BIGINT] NOT NULL , 100 [SCHED_TIME] [BIGINT] NOT NULL , 101 [PRIORITY] [INTEGER] NOT NULL , 102 [STATE] [NVARCHAR] (16) NOT NULL, 103 [JOB_NAME] [NVARCHAR] (150) NULL , 104 [JOB_GROUP] [NVARCHAR] (150) NULL , 105 [IS_NONCONCURRENT] BIT NULL , 106 [REQUESTS_RECOVERY] BIT NULL 107 ) 108 GO 109 110 CREATE TABLE [dbo].[QRTZ_PAUSED_TRIGGER_GRPS] ( 111 [SCHED_NAME] [NVARCHAR] (120) NOT NULL , 112 [TRIGGER_GROUP] [NVARCHAR] (150) NOT NULL 113 ) 114 GO 115 116 CREATE TABLE [dbo].[QRTZ_SCHEDULER_STATE] ( 117 [SCHED_NAME] [NVARCHAR] (120) NOT NULL , 118 [INSTANCE_NAME] [NVARCHAR] (200) NOT NULL , 119 [LAST_CHECKIN_TIME] [BIGINT] NOT NULL , 120 [CHECKIN_INTERVAL] [BIGINT] NOT NULL 121 ) 122 GO 123 124 CREATE TABLE [dbo].[QRTZ_LOCKS] ( 125 [SCHED_NAME] [NVARCHAR] (120) NOT NULL , 126 [LOCK_NAME] [NVARCHAR] (40) NOT NULL 127 ) 128 GO 129 130 CREATE TABLE [dbo].[QRTZ_JOB_DETAILS] ( 131 [SCHED_NAME] [NVARCHAR] (120) NOT NULL , 132 [JOB_NAME] [NVARCHAR] (150) NOT NULL , 133 [JOB_GROUP] [NVARCHAR] (150) NOT NULL , 134 [DESCRIPTION] [NVARCHAR] (250) NULL , 135 [JOB_CLASS_NAME] [NVARCHAR] (250) NOT NULL , 136 [IS_DURABLE] BIT NOT NULL , 137 [IS_NONCONCURRENT] BIT NOT NULL , 138 [IS_UPDATE_DATA] BIT NOT NULL , 139 [REQUESTS_RECOVERY] BIT NOT NULL , 140 [JOB_DATA] [IMAGE] NULL 141 ) 142 GO 143 144 CREATE TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] ( 145 [SCHED_NAME] [NVARCHAR] (120) NOT NULL , 146 [TRIGGER_NAME] [NVARCHAR] (150) NOT NULL , 147 [TRIGGER_GROUP] [NVARCHAR] (150) NOT NULL , 148 [REPEAT_COUNT] [INTEGER] NOT NULL , 149 [REPEAT_INTERVAL] [BIGINT] NOT NULL , 150 [TIMES_TRIGGERED] [INTEGER] NOT NULL 151 ) 152 GO 153 154 CREATE TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] ( 155 [SCHED_NAME] [NVARCHAR] (120) NOT NULL , 156 [TRIGGER_NAME] [NVARCHAR] (150) NOT NULL , 157 [TRIGGER_GROUP] [NVARCHAR] (150) NOT NULL , 158 [STR_PROP_1] [NVARCHAR] (512) NULL, 159 [STR_PROP_2] [NVARCHAR] (512) NULL, 160 [STR_PROP_3] [NVARCHAR] (512) NULL, 161 [INT_PROP_1] [INT] NULL, 162 [INT_PROP_2] [INT] NULL, 163 [LONG_PROP_1] [BIGINT] NULL, 164 [LONG_PROP_2] [BIGINT] NULL, 165 [DEC_PROP_1] [NUMERIC] (13,4) NULL, 166 [DEC_PROP_2] [NUMERIC] (13,4) NULL, 167 [BOOL_PROP_1] BIT NULL, 168 [BOOL_PROP_2] BIT NULL, 169 ) 170 GO 171 172 CREATE TABLE [dbo].[QRTZ_BLOB_TRIGGERS] ( 173 [SCHED_NAME] [NVARCHAR] (120) NOT NULL , 174 [TRIGGER_NAME] [NVARCHAR] (150) NOT NULL , 175 [TRIGGER_GROUP] [NVARCHAR] (150) NOT NULL , 176 [BLOB_DATA] [IMAGE] NULL 177 ) 178 GO 179 180 CREATE TABLE [dbo].[QRTZ_TRIGGERS] ( 181 [SCHED_NAME] [NVARCHAR] (120) NOT NULL , 182 [TRIGGER_NAME] [NVARCHAR] (150) NOT NULL , 183 [TRIGGER_GROUP] [NVARCHAR] (150) NOT NULL , 184 [JOB_NAME] [NVARCHAR] (150) NOT NULL , 185 [JOB_GROUP] [NVARCHAR] (150) NOT NULL , 186 [DESCRIPTION] [NVARCHAR] (250) NULL , 187 [NEXT_FIRE_TIME] [BIGINT] NULL , 188 [PREV_FIRE_TIME] [BIGINT] NULL , 189 [PRIORITY] [INTEGER] NULL , 190 [TRIGGER_STATE] [NVARCHAR] (16) NOT NULL , 191 [TRIGGER_TYPE] [NVARCHAR] (8) NOT NULL , 192 [START_TIME] [BIGINT] NOT NULL , 193 [END_TIME] [BIGINT] NULL , 194 [CALENDAR_NAME] [NVARCHAR] (200) NULL , 195 [MISFIRE_INSTR] [INTEGER] NULL , 196 [JOB_DATA] [IMAGE] NULL 197 ) 198 GO 199 200 ALTER TABLE [dbo].[QRTZ_CALENDARS] WITH NOCHECK ADD 201 CONSTRAINT [PK_QRTZ_CALENDARS] PRIMARY KEY CLUSTERED 202 ( 203 [SCHED_NAME], 204 [CALENDAR_NAME] 205 ) 206 GO 207 208 ALTER TABLE [dbo].[QRTZ_CRON_TRIGGERS] WITH NOCHECK ADD 209 CONSTRAINT [PK_QRTZ_CRON_TRIGGERS] PRIMARY KEY CLUSTERED 210 ( 211 [SCHED_NAME], 212 [TRIGGER_NAME], 213 [TRIGGER_GROUP] 214 ) 215 GO 216 217 ALTER TABLE [dbo].[QRTZ_FIRED_TRIGGERS] WITH NOCHECK ADD 218 CONSTRAINT [PK_QRTZ_FIRED_TRIGGERS] PRIMARY KEY CLUSTERED 219 ( 220 [SCHED_NAME], 221 [ENTRY_ID] 222 ) 223 GO 224 225 ALTER TABLE [dbo].[QRTZ_PAUSED_TRIGGER_GRPS] WITH NOCHECK ADD 226 CONSTRAINT [PK_QRTZ_PAUSED_TRIGGER_GRPS] PRIMARY KEY CLUSTERED 227 ( 228 [SCHED_NAME], 229 [TRIGGER_GROUP] 230 ) 231 GO 232 233 ALTER TABLE [dbo].[QRTZ_SCHEDULER_STATE] WITH NOCHECK ADD 234 CONSTRAINT [PK_QRTZ_SCHEDULER_STATE] PRIMARY KEY CLUSTERED 235 ( 236 [SCHED_NAME], 237 [INSTANCE_NAME] 238 ) 239 GO 240 241 ALTER TABLE [dbo].[QRTZ_LOCKS] WITH NOCHECK ADD 242 CONSTRAINT [PK_QRTZ_LOCKS] PRIMARY KEY CLUSTERED 243 ( 244 [SCHED_NAME], 245 [LOCK_NAME] 246 ) 247 GO 248 249 ALTER TABLE [dbo].[QRTZ_JOB_DETAILS] WITH NOCHECK ADD 250 CONSTRAINT [PK_QRTZ_JOB_DETAILS] PRIMARY KEY CLUSTERED 251 ( 252 [SCHED_NAME], 253 [JOB_NAME], 254 [JOB_GROUP] 255 ) 256 GO 257 258 ALTER TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] WITH NOCHECK ADD 259 CONSTRAINT [PK_QRTZ_SIMPLE_TRIGGERS] PRIMARY KEY CLUSTERED 260 ( 261 [SCHED_NAME], 262 [TRIGGER_NAME], 263 [TRIGGER_GROUP] 264 ) 265 GO 266 267 ALTER TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] WITH NOCHECK ADD 268 CONSTRAINT [PK_QRTZ_SIMPROP_TRIGGERS] PRIMARY KEY CLUSTERED 269 ( 270 [SCHED_NAME], 271 [TRIGGER_NAME], 272 [TRIGGER_GROUP] 273 ) 274 GO 275 276 ALTER TABLE [dbo].[QRTZ_TRIGGERS] WITH NOCHECK ADD 277 CONSTRAINT [PK_QRTZ_TRIGGERS] PRIMARY KEY CLUSTERED 278 ( 279 [SCHED_NAME], 280 [TRIGGER_NAME], 281 [TRIGGER_GROUP] 282 ) 283 GO 284 285 ALTER TABLE [dbo].QRTZ_BLOB_TRIGGERS WITH NOCHECK ADD 286 CONSTRAINT [PK_QRTZ_BLOB_TRIGGERS] PRIMARY KEY CLUSTERED 287 ( 288 [SCHED_NAME], 289 [TRIGGER_NAME], 290 [TRIGGER_GROUP] 291 ) 292 GO 293 294 ALTER TABLE [dbo].[QRTZ_CRON_TRIGGERS] ADD 295 CONSTRAINT [FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY 296 ( 297 [SCHED_NAME], 298 [TRIGGER_NAME], 299 [TRIGGER_GROUP] 300 ) REFERENCES [dbo].[QRTZ_TRIGGERS] ( 301 [SCHED_NAME], 302 [TRIGGER_NAME], 303 [TRIGGER_GROUP] 304 ) ON DELETE CASCADE 305 GO 306 307 ALTER TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] ADD 308 CONSTRAINT [FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY 309 ( 310 [SCHED_NAME], 311 [TRIGGER_NAME], 312 [TRIGGER_GROUP] 313 ) REFERENCES [dbo].[QRTZ_TRIGGERS] ( 314 [SCHED_NAME], 315 [TRIGGER_NAME], 316 [TRIGGER_GROUP] 317 ) ON DELETE CASCADE 318 GO 319 320 ALTER TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] ADD 321 CONSTRAINT [FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY 322 ( 323 [SCHED_NAME], 324 [TRIGGER_NAME], 325 [TRIGGER_GROUP] 326 ) REFERENCES [dbo].[QRTZ_TRIGGERS] ( 327 [SCHED_NAME], 328 [TRIGGER_NAME], 329 [TRIGGER_GROUP] 330 ) ON DELETE CASCADE 331 GO 332 333 ALTER TABLE [dbo].[QRTZ_TRIGGERS] ADD 334 CONSTRAINT [FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS] FOREIGN KEY 335 ( 336 [SCHED_NAME], 337 [JOB_NAME], 338 [JOB_GROUP] 339 ) REFERENCES [dbo].[QRTZ_JOB_DETAILS] ( 340 [SCHED_NAME], 341 [JOB_NAME], 342 [JOB_GROUP] 343 ) 344 GO 345 346 CREATE INDEX IDX_QRTZ_T_J ON QRTZ_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP) 347 CREATE INDEX IDX_QRTZ_T_JG ON QRTZ_TRIGGERS(SCHED_NAME,JOB_GROUP) 348 CREATE INDEX IDX_QRTZ_T_C ON QRTZ_TRIGGERS(SCHED_NAME,CALENDAR_NAME) 349 CREATE INDEX IDX_QRTZ_T_G ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP) 350 CREATE INDEX IDX_QRTZ_T_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE) 351 CREATE INDEX IDX_QRTZ_T_N_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE) 352 CREATE INDEX IDX_QRTZ_T_N_G_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE) 353 CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME ON QRTZ_TRIGGERS(SCHED_NAME,NEXT_FIRE_TIME) 354 CREATE INDEX IDX_QRTZ_T_NFT_ST ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME) 355 CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME) 356 CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE) 357 CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE) 358 359 CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME) 360 CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY) 361 CREATE INDEX IDX_QRTZ_FT_J_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP) 362 CREATE INDEX IDX_QRTZ_FT_JG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_GROUP) 363 CREATE INDEX IDX_QRTZ_FT_T_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 364 CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP) 365 GO
a).QRTZ_JOB_DETAILS 存储Job详细信息,IS_DURABLE-是否持久化,JOB_CLASS_NAME-具体实现类和命名空间
b).QRTZ_BLOB_TRIGGERS 触发器存为二进制大对象类型用于Quartz用户自己触发数据库定制自己的触发器
c).QRTZ_TRIGGERS:触发器信息,包含:job的名,组外键,[DESCRIPTION]触发器的描述等基本信息,还有[START_TIME]开始执行时间,[END_TIME]结束执行时间,[PREV_FIRE_TIME]上次执行时间,[NEXT_FIRE_TIME]下次执行时间,[TRIGGER_TYPE]触发器类型:simple和cron,[TRIGGER_STATE]执行状态:WAITING,PAUSED,ACQUIRED分别为:等待,暂停,运行中
d).QRTZ_SCHEDULER_STATE:存储集群中note实例信息,quartz会定时读取该表的信息判断集群中每个实例的当前状态,INSTANCE_NAME:之前配置文件中org.quartz.scheduler.instanceId配置的名字,就会写入该字段,如果设置为AUTO,quartz会根据物理机名和当前时间产生一个名字。 [LAST_CHECKIN_TIME]上次检查时间,[CHECKIN_INTERVAL]检查间隔时间
e).QRTZ_PAUSED_TRIGGER_GRPS:暂停的任务组信息
f).QRTZ_LOCKS:悲观锁发生的记录信息
g).QRTZ_FIRED_TRIGGERS:正在运行的触发器信息
h).QRTZ_SIMPLE_TRIGGERS:简单的触发器详细信息
i).QRTZ_CRON_TRIGGERS:保存cron表达式。
4.使用topshelf构建window服务
1 HostFactory.Run(x => 2 { 3 //x.UseLog4Net(); 4 5 x.Service<MyServiceRunner>(); 6 7 x.SetDescription("hi"); 8 x.SetDisplayName("hi服务"); 9 x.SetServiceName("hiJob"); 10 x.EnablePauseAndContinue(); 11 });
5.在MySerivceRunner的构造函数中配置Quartz
1 public class MyServiceRunner : ServiceControl, ServiceSuspend 2 { 3 private readonly IScheduler scheduler; 4 5 public MyServiceRunner() 6 { 7 //1.首先创建一个作业调度池 8 var properties = new System.Collections.Specialized.NameValueCollection(); 9 //存储类型 10 properties["quartz.jobStore.type"] = "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz"; 11 12 //驱动类型 13 properties["quartz.jobStore.driverDelegateType"] = "Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz"; //数据源名称 14 properties["quartz.jobStore.dataSource"] = "TestDB"; 15 16 //连接字符串 17 properties["quartz.dataSource.TestDB.connectionString"] = @"server=.; Initial Catalog=TestDB; User Id =****; pwd=*****;"; 18 //sqlserver版本 19 properties["quartz.dataSource.TestDB.provider"] = "SqlServer-20"; 20 21 //是否集群 22 properties["quartz.jobStore.clustered"] = "true"; 23 properties["quartz.scheduler.instanceId"] = "AUTO"; 24 25 var factory = new StdSchedulerFactory(properties); 26 27 scheduler = factory.GetScheduler(); 28 29 scheduler.Start(); 30 31 var jobKey = JobKey.Create("myjob8", "group"); 32 33 if (scheduler.CheckExists(jobKey)) 34 { 35 Console.WriteLine("当前job已经存在,无需调度:{0}", jobKey.ToString()); 36 } 37 else 38 { 39 IJobDetail job = JobBuilder.Create<HiJob>() 40 .WithDescription("使用quartz进行持久化存储") 41 .StoreDurably() 42 .RequestRecovery() 43 .WithIdentity(jobKey) 44 .UsingJobData("count", 1) 45 .Build(); 46 47 ITrigger trigger = TriggerBuilder.Create().WithSimpleSchedule(x => x.WithIntervalInSeconds(2).RepeatForever()) 48 .Build(); 49 scheduler.ScheduleJob(job, trigger); 50 } 51 } 52 53 public bool Start(HostControl hostControl) 54 { 55 LogManager.Adapter = new Common.Logging.Simple.TraceLoggerFactoryAdapter() { Level = LogLevel.All }; 56 scheduler.Start(); 57 return true; 58 } 59 60 public bool Stop(HostControl hostControl) 61 { 62 scheduler.Shutdown(false); 63 return true; 64 } 65 66 public bool Continue(HostControl hostControl) 67 { 68 scheduler.ResumeAll(); 69 return true; 70 } 71 72 public bool Pause(HostControl hostControl) 73 { 74 scheduler.PauseAll(); 75 return true; 76 } 77 }
接下来就是HiJob了,实现IJob接口中的Execute方法,里面就是具体的实现业务逻辑入口了,为了能看出效果我只是写了一个数据库插入数据,也可以做其他操作。
1 SqlConnection con = new SqlConnection("Data Source=.; Initial Catalog=YiCheRoot; User Id =sa; pwd=Yche.20170413;"); 2 con.Open(); 3 string str1 = "b"; 4 string str = "insert into test (groupname) values(‘" + str1 + "‘)"; 5 SqlCommand com = new SqlCommand(str, con); 6 int intcont = Convert.ToInt32(com.ExecuteScalar()); 7 con.Close();
到这就差不多完成了,问题是怎么测试多机热备的问题呢,总不能去部署到多台机器吧,其实很简单,就是JobKey一样,创建几个不同的服务名称就行了。代码中已经标红了。效果就不贴图了,有问题可以私信我,源码也不提供了。