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

时间: 2024-08-26 22:54:59

SqlServer+Topshelf+Quartznet做集群,定时任务分布式处理的相关文章

Spring+Quartz框架实现定时任务(集群,分布式)

1.定时任务的必要性: 定时任务在应用中的重要性不言而喻,大多是应用,特别是金融应用更是离不开定时任务,能用定时任务来处理异常订单,完成跑批,定时活动(双11)等.在初期应用的访问量并不是那么大,一台服务器完全满足使用,但是随着用户量.业务量的逐日增加,应用中会有很多定时任务需要执行,一台服务器已经不能满足使用,因此需要把应用给部署到集群中,前端通过nginx代理实现访问. 2.集群使用定时任务的问题:目前大部分在集群中处理定时任务的方式不是正真的分布式处理方式,而是一种伪分布式,这种方式存在一

集群、分布式、负载均衡区别与联系

1.Linux集群主要分成三大类( 高可用集群, 负载均衡集群,科学计算集群)(下面只介绍负载均衡集群) 负载均衡集群(Load Balance Cluster) 负载均衡系统:集群中所有的节点都处于活动状态,它们分摊系统的工作负载.一般Web服务器集群.数据库集群和应用服务器集群都属于这种类型. 负载均衡集群一般用于相应网络请求的网页服务器,数据库服务器.这种集群可以在接到请求时,检查接受请求较少,不繁忙的服务器,并把请求转到这些服务器上.从检查其他服务器状态这一点上看,负载均衡和容错集群很接

原!总结 quartz集群 定时任务 测试运行ok

由于项目优化重构,想将定时任务从quartz单机模式变成集群或分布式的方式.于是,百度了一圈....修修改改...用集群的方式部署定时任务,测试可以... 集群?分布式?什么区别? 集群:同一个业务,部署在多个服务器上 分布式:一个业务分拆多个子业务,部署在不同的服务器上 或者说 集群:是指在多台不同的服务器中部署相同应用或服务模块,构成一个集群,通过负载均衡设备对外提供服务. 分布式:是指在多台不同的服务器中部署不同的服务模块,通过远程调用协同工作,对外提供服务. 平时常用的quartz单机模

jeecg 3.7.1 新版功能,集群定时任务动态发布模块 使用规则

jeecg 3.7.1  集群定时任务动态发布模块 使用规则 新版特性:    支持集群定时任务,支持分布式. 菜单路径: 系统监控-->定时任务 字段说明: 任务ID.任务说明:自定义即可 cron表达式: 定义任务触发的时间规则.提供一个在线生成cron的地址,http://cron.qqe2.com/ 任务类名: 执行定时任务的业务类,实现org.quartz.Job接口,任务触发时系统自动执行execute方法.格式:包名.类名,举例:com.mypackage.ClassName 执行

集群与分布式 如何理解(自己的理解)

集群 与 分布式 如何理解 一. 概念理解 集群的理解:就是一台计算机处理不了太多的事情 ,需要大家组合在一起来完成一件事情. 分布式的理解:就是把一件事情分成好几个部分 ,每个人做其中的一部分. 二.图解 分布式 负责均衡集群 三.集群的种类: 负载均衡集群(Load Balance):Nginx反向代理  .DNS 轮训巡.LVS(Nat 模式 .隧道模式.直连路由) 高可用集群(High Availabe):Keepalive .Heartbeat 并行计算集群(HPC):不了解 申明:这

Hadoop学习笔记_4_实施Hadoop集群 --伪分布式安装

实施Hadoop集群 --伪分布式安装 准备与配置安装环境 安装虚拟机和linux,虚拟机推荐使用vmware,PC可以使用workstation,服务器可以使用ESXi,在管理上比较方便.ESXi还可以通过拷贝镜像文件复制虚拟机,复制后自动修改网卡号和ip,非常快捷.如果只是实验用途,硬盘大约预留20-30G空间. 以Centos为例,分区可以选择默认[如果想要手动分区,请参考博客:http://blog.csdn.net/zjf280441589/article/details/175485

集群、分布式的区别

1.Linux集群主要分成三大类( 高可用集群, 负载均衡集群,科学计算集群)(下面只介绍负载均衡集群) 负载均衡集群(Load Balance Cluster)负载均衡系统:集群中所有的节点都处于活动状态,它们分摊系统的工作负载.一般Web服务器集群.数据库集群和应用服务器集群都属于这种类型. 负载均衡集群一般用于相应网络请求的网页服务器,数据库服务器.这种集群可以在接到请求时,检查接受请求较少,不繁忙的服务器,并把请求转到这些服务器上.从检查其他服务器状态这一点上看,负载均衡和容错集群很接近

集群、分布式、负载均衡

集群和负载均衡的概念 负载均衡LVS集群详解 大型电子商务网站架构之--分布式可扩展数据库架构 负载均衡有两种:软负载lvs;硬负载f5. 水平切分数据库: 可以降低单台机器的负载,同时最大限度的降低了了宕机造成的损失. 负载均衡: 有效的降低了单台 机器的访问负载,降低了宕机的可能性: 集群: 解决了数据库宕机带来的单点数据库不能访问的问题: 读写分离: 最大限度了提高了应用中读取 (Read)数据的速度和并发量. 1.Linux集群主要分成三大类( 高可用集群, 负载均衡集群,科学计算集群)

Redis集群与分布式介绍以及搭建Redis-Cluster

1 Redis集群 1.1 什么是集群 集群就是很多服务器组成的一个网络.指的是将多台服务器集中在一起,实现同一业务. 1.2 为什么要集群 一台服务器不能满足开发需要的时候,需要多台服务器来支持.这个时候就需要做集群,但是集群往往伴随 着分布式. 1.3 集群的特性及能力 1.集群的两大关键特性: 可扩展性----集群的性能不限于单一的服务实体,新的服务实体可以动态地加入到集群,从而增强集群的性能.动态添加服务器高可用性----集群通过服务实体冗余使客户端免于轻易遇到out of servic