接触Quartznet之前,老东家用的是总监自己写的分布式任务框架,好用但是配置麻烦,unity,一个微软容器,配置节点错一个,整个使用到unity文件的项目全部跑不起来,这后果真的受不了。。。

  目前公司呢,没什么框架,全都是自己研究,自己找,合适的就用,独立自主,可是这样的方式真的好么,一个员工离职,或许他引进的东西别人要推翻重写,代价也不小。。算了还是说下自己用到的东西吧。这里只是简单记录,有问题可以私信。

  1.新建控制台项目,这里就叫DistributedService;

  2.通过NuGet包管理器,或者命令行,添加Topshelf,Quartz;

  3.既然分布式集群,多机热备,就采用官方的SQL Server持久化存储,sql脚本地址:https://github.com/quartznet/quartznet/tree/master/database

  

   具体脚本内容

    

 USE 数据库名
GO IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1)
ALTER TABLE [dbo].[QRTZ_TRIGGERS] DROP CONSTRAINT FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS
GO IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1)
ALTER TABLE [dbo].[QRTZ_CRON_TRIGGERS] DROP CONSTRAINT FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS
GO IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1)
ALTER TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] DROP CONSTRAINT FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS
GO IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1)
ALTER TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] DROP CONSTRAINT FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS
GO 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]'))
ALTER TABLE [dbo].[QRTZ_JOB_LISTENERS] DROP CONSTRAINT [FK_QRTZ_JOB_LISTENERS_QRTZ_JOB_DETAILS] 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]'))
ALTER TABLE [dbo].[QRTZ_TRIGGER_LISTENERS] DROP CONSTRAINT [FK_QRTZ_TRIGGER_LISTENERS_QRTZ_TRIGGERS] IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_CALENDARS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
DROP TABLE [dbo].[QRTZ_CALENDARS]
GO IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_CRON_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
DROP TABLE [dbo].[QRTZ_CRON_TRIGGERS]
GO IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_BLOB_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
DROP TABLE [dbo].[QRTZ_BLOB_TRIGGERS]
GO IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_FIRED_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
DROP TABLE [dbo].[QRTZ_FIRED_TRIGGERS]
GO IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_PAUSED_TRIGGER_GRPS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
DROP TABLE [dbo].[QRTZ_PAUSED_TRIGGER_GRPS]
GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[QRTZ_JOB_LISTENERS]') AND type in (N'U'))
DROP TABLE [dbo].[QRTZ_JOB_LISTENERS] IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_SCHEDULER_STATE]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
DROP TABLE [dbo].[QRTZ_SCHEDULER_STATE]
GO IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_LOCKS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
DROP TABLE [dbo].[QRTZ_LOCKS]
GO
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[QRTZ_TRIGGER_LISTENERS]') AND type in (N'U'))
DROP TABLE [dbo].[QRTZ_TRIGGER_LISTENERS] IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_JOB_DETAILS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
DROP TABLE [dbo].[QRTZ_JOB_DETAILS]
GO IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_SIMPLE_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
DROP TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS]
GO IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_SIMPROP_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
DROP TABLE [dbo].QRTZ_SIMPROP_TRIGGERS
GO IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
DROP TABLE [dbo].[QRTZ_TRIGGERS]
GO CREATE TABLE [dbo].[QRTZ_CALENDARS] (
[SCHED_NAME] [NVARCHAR] (120) NOT NULL ,
[CALENDAR_NAME] [NVARCHAR] (200) NOT NULL ,
[CALENDAR] [IMAGE] NOT NULL
)
GO CREATE TABLE [dbo].[QRTZ_CRON_TRIGGERS] (
[SCHED_NAME] [NVARCHAR] (120) NOT NULL ,
[TRIGGER_NAME] [NVARCHAR] (150) NOT NULL ,
[TRIGGER_GROUP] [NVARCHAR] (150) NOT NULL ,
[CRON_EXPRESSION] [NVARCHAR] (120) NOT NULL ,
[TIME_ZONE_ID] [NVARCHAR] (80)
)
GO CREATE TABLE [dbo].[QRTZ_FIRED_TRIGGERS] (
[SCHED_NAME] [NVARCHAR] (120) NOT NULL ,
[ENTRY_ID] [NVARCHAR] (140) NOT NULL ,
[TRIGGER_NAME] [NVARCHAR] (150) NOT NULL ,
[TRIGGER_GROUP] [NVARCHAR] (150) NOT NULL ,
[INSTANCE_NAME] [NVARCHAR] (200) NOT NULL ,
[FIRED_TIME] [BIGINT] NOT NULL ,
[SCHED_TIME] [BIGINT] NOT NULL ,
[PRIORITY] [INTEGER] NOT NULL ,
[STATE] [NVARCHAR] (16) NOT NULL,
[JOB_NAME] [NVARCHAR] (150) NULL ,
[JOB_GROUP] [NVARCHAR] (150) NULL ,
[IS_NONCONCURRENT] BIT NULL ,
[REQUESTS_RECOVERY] BIT NULL
)
GO CREATE TABLE [dbo].[QRTZ_PAUSED_TRIGGER_GRPS] (
[SCHED_NAME] [NVARCHAR] (120) NOT NULL ,
[TRIGGER_GROUP] [NVARCHAR] (150) NOT NULL
)
GO CREATE TABLE [dbo].[QRTZ_SCHEDULER_STATE] (
[SCHED_NAME] [NVARCHAR] (120) NOT NULL ,
[INSTANCE_NAME] [NVARCHAR] (200) NOT NULL ,
[LAST_CHECKIN_TIME] [BIGINT] NOT NULL ,
[CHECKIN_INTERVAL] [BIGINT] NOT NULL
)
GO CREATE TABLE [dbo].[QRTZ_LOCKS] (
[SCHED_NAME] [NVARCHAR] (120) NOT NULL ,
[LOCK_NAME] [NVARCHAR] (40) NOT NULL
)
GO CREATE TABLE [dbo].[QRTZ_JOB_DETAILS] (
[SCHED_NAME] [NVARCHAR] (120) NOT NULL ,
[JOB_NAME] [NVARCHAR] (150) NOT NULL ,
[JOB_GROUP] [NVARCHAR] (150) NOT NULL ,
[DESCRIPTION] [NVARCHAR] (250) NULL ,
[JOB_CLASS_NAME] [NVARCHAR] (250) NOT NULL ,
[IS_DURABLE] BIT NOT NULL ,
[IS_NONCONCURRENT] BIT NOT NULL ,
[IS_UPDATE_DATA] BIT NOT NULL ,
[REQUESTS_RECOVERY] BIT NOT NULL ,
[JOB_DATA] [IMAGE] NULL
)
GO CREATE TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] (
[SCHED_NAME] [NVARCHAR] (120) NOT NULL ,
[TRIGGER_NAME] [NVARCHAR] (150) NOT NULL ,
[TRIGGER_GROUP] [NVARCHAR] (150) NOT NULL ,
[REPEAT_COUNT] [INTEGER] NOT NULL ,
[REPEAT_INTERVAL] [BIGINT] NOT NULL ,
[TIMES_TRIGGERED] [INTEGER] NOT NULL
)
GO CREATE TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] (
[SCHED_NAME] [NVARCHAR] (120) NOT NULL ,
[TRIGGER_NAME] [NVARCHAR] (150) NOT NULL ,
[TRIGGER_GROUP] [NVARCHAR] (150) NOT NULL ,
[STR_PROP_1] [NVARCHAR] (512) NULL,
[STR_PROP_2] [NVARCHAR] (512) NULL,
[STR_PROP_3] [NVARCHAR] (512) NULL,
[INT_PROP_1] [INT] NULL,
[INT_PROP_2] [INT] NULL,
[LONG_PROP_1] [BIGINT] NULL,
[LONG_PROP_2] [BIGINT] NULL,
[DEC_PROP_1] [NUMERIC] (13,4) NULL,
[DEC_PROP_2] [NUMERIC] (13,4) NULL,
[BOOL_PROP_1] BIT NULL,
[BOOL_PROP_2] BIT NULL,
)
GO CREATE TABLE [dbo].[QRTZ_BLOB_TRIGGERS] (
[SCHED_NAME] [NVARCHAR] (120) NOT NULL ,
[TRIGGER_NAME] [NVARCHAR] (150) NOT NULL ,
[TRIGGER_GROUP] [NVARCHAR] (150) NOT NULL ,
[BLOB_DATA] [IMAGE] NULL
)
GO CREATE TABLE [dbo].[QRTZ_TRIGGERS] (
[SCHED_NAME] [NVARCHAR] (120) NOT NULL ,
[TRIGGER_NAME] [NVARCHAR] (150) NOT NULL ,
[TRIGGER_GROUP] [NVARCHAR] (150) NOT NULL ,
[JOB_NAME] [NVARCHAR] (150) NOT NULL ,
[JOB_GROUP] [NVARCHAR] (150) NOT NULL ,
[DESCRIPTION] [NVARCHAR] (250) NULL ,
[NEXT_FIRE_TIME] [BIGINT] NULL ,
[PREV_FIRE_TIME] [BIGINT] NULL ,
[PRIORITY] [INTEGER] NULL ,
[TRIGGER_STATE] [NVARCHAR] (16) NOT NULL ,
[TRIGGER_TYPE] [NVARCHAR] (8) NOT NULL ,
[START_TIME] [BIGINT] NOT NULL ,
[END_TIME] [BIGINT] NULL ,
[CALENDAR_NAME] [NVARCHAR] (200) NULL ,
[MISFIRE_INSTR] [INTEGER] NULL ,
[JOB_DATA] [IMAGE] NULL
)
GO ALTER TABLE [dbo].[QRTZ_CALENDARS] WITH NOCHECK ADD
CONSTRAINT [PK_QRTZ_CALENDARS] PRIMARY KEY CLUSTERED
(
[SCHED_NAME],
[CALENDAR_NAME]
)
GO ALTER TABLE [dbo].[QRTZ_CRON_TRIGGERS] WITH NOCHECK ADD
CONSTRAINT [PK_QRTZ_CRON_TRIGGERS] PRIMARY KEY CLUSTERED
(
[SCHED_NAME],
[TRIGGER_NAME],
[TRIGGER_GROUP]
)
GO ALTER TABLE [dbo].[QRTZ_FIRED_TRIGGERS] WITH NOCHECK ADD
CONSTRAINT [PK_QRTZ_FIRED_TRIGGERS] PRIMARY KEY CLUSTERED
(
[SCHED_NAME],
[ENTRY_ID]
)
GO ALTER TABLE [dbo].[QRTZ_PAUSED_TRIGGER_GRPS] WITH NOCHECK ADD
CONSTRAINT [PK_QRTZ_PAUSED_TRIGGER_GRPS] PRIMARY KEY CLUSTERED
(
[SCHED_NAME],
[TRIGGER_GROUP]
)
GO ALTER TABLE [dbo].[QRTZ_SCHEDULER_STATE] WITH NOCHECK ADD
CONSTRAINT [PK_QRTZ_SCHEDULER_STATE] PRIMARY KEY CLUSTERED
(
[SCHED_NAME],
[INSTANCE_NAME]
)
GO ALTER TABLE [dbo].[QRTZ_LOCKS] WITH NOCHECK ADD
CONSTRAINT [PK_QRTZ_LOCKS] PRIMARY KEY CLUSTERED
(
[SCHED_NAME],
[LOCK_NAME]
)
GO ALTER TABLE [dbo].[QRTZ_JOB_DETAILS] WITH NOCHECK ADD
CONSTRAINT [PK_QRTZ_JOB_DETAILS] PRIMARY KEY CLUSTERED
(
[SCHED_NAME],
[JOB_NAME],
[JOB_GROUP]
)
GO ALTER TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] WITH NOCHECK ADD
CONSTRAINT [PK_QRTZ_SIMPLE_TRIGGERS] PRIMARY KEY CLUSTERED
(
[SCHED_NAME],
[TRIGGER_NAME],
[TRIGGER_GROUP]
)
GO ALTER TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] WITH NOCHECK ADD
CONSTRAINT [PK_QRTZ_SIMPROP_TRIGGERS] PRIMARY KEY CLUSTERED
(
[SCHED_NAME],
[TRIGGER_NAME],
[TRIGGER_GROUP]
)
GO ALTER TABLE [dbo].[QRTZ_TRIGGERS] WITH NOCHECK ADD
CONSTRAINT [PK_QRTZ_TRIGGERS] PRIMARY KEY CLUSTERED
(
[SCHED_NAME],
[TRIGGER_NAME],
[TRIGGER_GROUP]
)
GO ALTER TABLE [dbo].QRTZ_BLOB_TRIGGERS WITH NOCHECK ADD
CONSTRAINT [PK_QRTZ_BLOB_TRIGGERS] PRIMARY KEY CLUSTERED
(
[SCHED_NAME],
[TRIGGER_NAME],
[TRIGGER_GROUP]
)
GO ALTER TABLE [dbo].[QRTZ_CRON_TRIGGERS] ADD
CONSTRAINT [FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY
(
[SCHED_NAME],
[TRIGGER_NAME],
[TRIGGER_GROUP]
) REFERENCES [dbo].[QRTZ_TRIGGERS] (
[SCHED_NAME],
[TRIGGER_NAME],
[TRIGGER_GROUP]
) ON DELETE CASCADE
GO ALTER TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] ADD
CONSTRAINT [FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY
(
[SCHED_NAME],
[TRIGGER_NAME],
[TRIGGER_GROUP]
) REFERENCES [dbo].[QRTZ_TRIGGERS] (
[SCHED_NAME],
[TRIGGER_NAME],
[TRIGGER_GROUP]
) ON DELETE CASCADE
GO ALTER TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] ADD
CONSTRAINT [FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY
(
[SCHED_NAME],
[TRIGGER_NAME],
[TRIGGER_GROUP]
) REFERENCES [dbo].[QRTZ_TRIGGERS] (
[SCHED_NAME],
[TRIGGER_NAME],
[TRIGGER_GROUP]
) ON DELETE CASCADE
GO ALTER TABLE [dbo].[QRTZ_TRIGGERS] ADD
CONSTRAINT [FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS] FOREIGN KEY
(
[SCHED_NAME],
[JOB_NAME],
[JOB_GROUP]
) REFERENCES [dbo].[QRTZ_JOB_DETAILS] (
[SCHED_NAME],
[JOB_NAME],
[JOB_GROUP]
)
GO CREATE INDEX IDX_QRTZ_T_J ON QRTZ_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP)
CREATE INDEX IDX_QRTZ_T_JG ON QRTZ_TRIGGERS(SCHED_NAME,JOB_GROUP)
CREATE INDEX IDX_QRTZ_T_C ON QRTZ_TRIGGERS(SCHED_NAME,CALENDAR_NAME)
CREATE INDEX IDX_QRTZ_T_G ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP)
CREATE INDEX IDX_QRTZ_T_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE)
CREATE INDEX IDX_QRTZ_T_N_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE)
CREATE INDEX IDX_QRTZ_T_N_G_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE)
CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME ON QRTZ_TRIGGERS(SCHED_NAME,NEXT_FIRE_TIME)
CREATE INDEX IDX_QRTZ_T_NFT_ST ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME)
CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME)
CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE)
CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE) CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME)
CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY)
CREATE INDEX IDX_QRTZ_FT_J_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP)
CREATE INDEX IDX_QRTZ_FT_JG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_GROUP)
CREATE INDEX IDX_QRTZ_FT_T_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP)
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服务

   HostFactory.Run(x =>
{
//x.UseLog4Net(); x.Service<MyServiceRunner>(); 7 x.SetDescription("hi");
8 x.SetDisplayName("hi服务");
9 x.SetServiceName("hiJob");
x.EnablePauseAndContinue();
});

5.在MySerivceRunner的构造函数中配置Quartz

  

    public class MyServiceRunner : ServiceControl, ServiceSuspend
{
private readonly IScheduler scheduler; public MyServiceRunner()
{
//1.首先创建一个作业调度池
var properties = new System.Collections.Specialized.NameValueCollection();
//存储类型
properties["quartz.jobStore.type"] = "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz"; //驱动类型
properties["quartz.jobStore.driverDelegateType"] = "Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz"; //数据源名称
properties["quartz.jobStore.dataSource"] = "TestDB"; //连接字符串
properties["quartz.dataSource.TestDB.connectionString"] = @"server=.; Initial Catalog=TestDB; User Id =****; pwd=*****;";
//sqlserver版本
properties["quartz.dataSource.TestDB.provider"] = "SqlServer-20"; //是否集群
properties["quartz.jobStore.clustered"] = "true";
properties["quartz.scheduler.instanceId"] = "AUTO"; var factory = new StdSchedulerFactory(properties); scheduler = factory.GetScheduler(); scheduler.Start(); var jobKey = JobKey.Create("myjob8", "group"); if (scheduler.CheckExists(jobKey))
{
Console.WriteLine("当前job已经存在,无需调度:{0}", jobKey.ToString());
}
else
{
IJobDetail job = JobBuilder.Create<HiJob>()
.WithDescription("使用quartz进行持久化存储")
.StoreDurably()
.RequestRecovery()
.WithIdentity(jobKey)
.UsingJobData("count", )
.Build(); ITrigger trigger = TriggerBuilder.Create().WithSimpleSchedule(x => x.WithIntervalInSeconds().RepeatForever())
.Build();
scheduler.ScheduleJob(job, trigger);
}
} public bool Start(HostControl hostControl)
{
LogManager.Adapter = new Common.Logging.Simple.TraceLoggerFactoryAdapter() { Level = LogLevel.All };
scheduler.Start();
return true;
} public bool Stop(HostControl hostControl)
{
scheduler.Shutdown(false);
return true;
} public bool Continue(HostControl hostControl)
{
scheduler.ResumeAll();
return true;
} public bool Pause(HostControl hostControl)
{
scheduler.PauseAll();
return true;
}
}

  接下来就是HiJob了,实现IJob接口中的Execute方法,里面就是具体的实现业务逻辑入口了,为了能看出效果我只是写了一个数据库插入数据,也可以做其他操作。

    SqlConnection con = new SqlConnection("Data Source=.; Initial Catalog=YiCheRoot; User Id =sa; pwd=Yche.20170413;");
con.Open();
string str1 = "b";
string str = "insert into test (groupname) values('" + str1 + "')";
SqlCommand com = new SqlCommand(str, con);
int intcont = Convert.ToInt32(com.ExecuteScalar());
con.Close();

  到这就差不多完成了,问题是怎么测试多机热备的问题呢,总不能去部署到多台机器吧,其实很简单,就是JobKey一样,创建几个不同的服务名称就行了。代码中已经标红了。效果就不贴图了,有问题可以私信我,源码也不提供了。

  划重点了,部署多台机器的时候,时间要做到同步!因为quartz依赖的是本机时间。

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

  1. Quartz集成springMVC 的方案二(持久化任务、集群和分布式)

    Quartz是一个开放源码项目,专注于任务调度器,提供了极为广泛的特性如持久化任务,集群和分布式任务等. Quartz核心是调度器,还采用多线程管理. 1.持久化任务:当应用程序停止运行时,所有调度信 ...

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

    jeecg 3.7.1  集群定时任务动态发布模块 使用规则   新版特性:    支持集群定时任务,支持分布式. 菜单路径: 系统监控-->定时任务 字段说明: 任务ID.任务说明:自定义即可 ...

  3. 乐观锁vs悲观锁, 集群vs分布式 , 微服务, 幂等性

    乐观锁: 总认为不会产生并发问题,因此不会上锁,更新时会判断其他线程在这之前有没有对数据进行修改,一般会使用版本号机制或CAS操作来实现 version: 数据上有数据版本号version字段,每次更 ...

  4. 传统应用、服务器集群、分布式、SOA各种架构的简单解释

    传统架构:无论是SE应用还是WEB应用,传统架构都是表现层---业务层---持久层---数据库   1000并发(tomcat单台500并发,tomcat一般做集群的话,节点数量不能太多,5个左右): ...

  5. web中的集群与分布式

    面试中经常会提到 集群 和 分布式.下面就来分别说说这两个在web开发中经常用到的开发方式. 集群: 集群是一组协同工作的服务实体,用以提供比单一服务实体更具扩展性与可用性的服务平台.在客户端看来,一 ...

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

    由于项目优化重构,想将定时任务从quartz单机模式变成集群或分布式的方式.于是,百度了一圈....修修改改...用集群的方式部署定时任务,测试可以... 集群?分布式?什么区别? 集群:同一个业务, ...

  7. Consul实现原理系列文章2: 用Gossip来做集群成员管理和消息广播

    工作中用到了Consul来做服务发现,之后一段时间里,我会陆续发一些文章来讲述Consul实现原理.这篇文章会讲述Consul是如何使用Gossip来做集群成员管理和消息广播的. Consul使用Go ...

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

    1 Redis集群 1.1 什么是集群 集群就是很多服务器组成的一个网络.指的是将多台服务器集中在一起,实现同一业务. 1.2 为什么要集群 一台服务器不能满足开发需要的时候,需要多台服务器来支持.这 ...

  9. Hadoop1.X集群完全分布式模式环境部署

    Hadoop1.X集群完全分布式模式环境部署 1 Hadoop简介 Hadoop是Apache软件基金会旗下的一个开源分布式计算平台.以Hadoop分布式文件系统(HDFS,Hadoop Distri ...

随机推荐

  1. 洛谷 P1012 拼数 [字符串]

    题目描述 设有n个正整数(n≤20),将它们联接成一排,组成一个最大的多位整数. 例如:n=3时,3个整数13,312,343联接成的最大整数为:34331213 又如:n=4时,4个整数7,13,4 ...

  2. ASP.NET Core 2.2 基础知识(十二) 发送 HTTP 请求

    可以注册 IHttpClientFactory 并将其用于配置和创建应用中的 HttpClient 实例. 这能带来以下好处: 提供一个中心位置,用于命名和配置逻辑 HttpClient 实例. 例如 ...

  3. [姿势]cpp - memset

    头文件:memory.h 可以刷的有: memset(array,,sizeof(array)); //全部赋0 memset(array,-,sizeof(array)); //全部赋-1 用法和用 ...

  4. 【数位dp】hdu3555 Bomb

    题意就是找0到n有多少个数中含有49.数据范围接近10^20 DP的状态是2维的dp[len][3]dp[len][0] 代表长度为len不含49的方案数dp[len][1] 代表长度为len不含49 ...

  5. 利用位操作进行IP地址的转化

    1)IPv4地址是一个32位的二进制数,通常被分割位4个“8位二进制数”,为了方便,通常使用“点分十进制”的形式表示成(a.b.c.d)的形式,其中,a,b,c,d都是0~255之间的十进制整数,另外 ...

  6. Android介绍

    Android系统的底层建立在Linux系统之上,该平台有操作系统,中间件,用户界面和应用软件4层组成,它采用一种被称为软件叠层(Software Stack)的方式进行构建. 1.应用程序层:And ...

  7. /etc/sudoer文件配置简析

    参考: http://blog.chinaunix.net/uid-26642180-id-3962245.html # User privilege specification root    AL ...

  8. iOS开发笔记_4自定义TabBar

    新博客:http://www.liuchendi.com 好多APP都使用的是自定义的TabBar,那这个功能应该如何实现呢?首先应该解决的问题就是,加载NavigationController的时候 ...

  9. JavaScript的map循环、forEach循环、filter循环、reduce循环、reduceRight循环

    1.map循环 let arr=[1,2,3,4]; arr.map(function(value,key,arr){ //值,索引,数组(默认为选定数组) return item; //如果没有re ...

  10. 关于java的关键字 transient

    我们都知道一个对象只要实现了Serilizable接口,这个对象就可以被序列化,Java的这种序列化模式为开发者提供了很多便利,我们可以不必关系具体序列化的过程,只要这个类实现了Serilizable ...