首页 > 代码库 > SqlServer+Topshelf+Quartznet做集群,定时任务分布式处理

SqlServer+Topshelf+Quartznet做集群,定时任务分布式处理

  接触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, NISFOREIGNKEY) = 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, NISFOREIGNKEY) = 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, NISFOREIGNKEY) = 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, NISFOREIGNKEY) = 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, NISUSERTABLE) = 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, NISUSERTABLE) = 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, NISUSERTABLE) = 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, NISUSERTABLE) = 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, NISUSERTABLE) = 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 (NU))
 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, NISUSERTABLE) = 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, NISUSERTABLE) = 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 (NU))
 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, NISUSERTABLE) = 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, NISUSERTABLE) = 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, NISUSERTABLE) = 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, NISUSERTABLE) = 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一样,创建几个不同的服务名称就行了。代码中已经标红了。效果就不贴图了,有问题可以私信我,源码也不提供了。

SqlServer+Topshelf+Quartznet做集群,定时任务分布式处理