t持久化与集群部署开发详解
Quartz.net持久化与集群部署开发详解
序言
我前边有几篇文章有介绍过quartz的基本使用语法与类库。但是他的执行计划都是被写在本地的xml文件中。无法做集群部署,我让它看起来脆弱不堪,那是我的罪过。
但是quart.net是经过许多大项目的锤炼,走到啦今天,支持集群高可用的开发方案那是一定的,今天我就给小结下我的quartz.net开发升级过程。
Quartz.net的数据库表结构
如果支持集群与持久化,单靠本机的内存和xml来保存计算任务调度的各种状态值,可想而知,是困难的。所以支持数据库这样的解决方案,OpenSymphony组织怎么可能会给遗漏。
官方提供的各种数据库脚本:https://github.com/quartznet/quartznet/tree/master/database/tables
下面我给大家展示下quartz任务调度的MS SQLSERVER表结构
创建表结构T-SQL脚本
部分我们扩展开发常用到的表及字段说明
1、QRTZ_JOB_DETAILS:存储的是job的详细信息,包括:[DESCRIPTION]描述,[IS_DURABLE]是否持久化,[JOB_DATA]持久化对象等基本信息。
2、QRTZ_TRIGGERS:触发器信息,包含:job的名,组外键,[DESCRIPTION]触发器的描述等基本信息,还有[START_TIME]开始执行时间,[END_TIME]结束执行时间,[PREV_FIRE_TIME]上次执行时间,[NEXT_FIRE_TIME]下次执行时间,[TRIGGER_TYPE]触发器类型:simple和cron,[TRIGGER_STATE]执行状态:WAITING,PAUSED,ACQUIRED分别为:等待,暂停,运行中。
3、QRTZ_CRON_TRIGGERS:保存cron表达式。
4、QRTZ_SCHEDULER_STATE:存储集群中note实例信息,quartz会定时读取该表的信息判断集群中每个实例的当前状态,INSTANCE_NAME:之前配置文件中org.quartz.scheduler.instanceId配置的名字,就会写入该字段,如果设置为AUTO,quartz会根据物理机名和当前时间产生一个名字。 [LAST_CHECKIN_TIME]上次检查时间,[CHECKIN_INTERVAL]检查间隔时间。
5、QRTZ_PAUSED_TRIGGER_GRPS:暂停的任务组信息。
6、QRTZ_LOCKS,悲观锁发生的记录信息。
7、QRTZ_FIRED_TRIGGERS,正在运行的触发器信息。
8、QRTZ_SIMPLE_TRIGGERS,简单的出发器详细信息。
9、QRTZ_BLOB_TRIGGERS,触发器存为二进制大对象类型(用于Quartz用户自己触发数据库定制自己的触发器,然而JobStore不明白怎么存放实例的时候)。
.net程序配置quartz数据库参数

- //1.首先创建一个作业调度池
- var properties = new NameValueCollection();
- //存储类型
- properties["quartz.jobStore.type"] = "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz";
- //表明前缀
- properties["quartz.jobStore.tablePrefix"] = "QRTZ_";
- //驱动类型
- properties["quartz.jobStore.driverDelegateType"] = "Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz"; //数据源名称
- properties["quartz.jobStore.dataSource"] = "myDS";
- //连接字符串
- properties["quartz.dataSource.myDS.connectionString"] = Config.QuartzConnStr;
- //sqlserver版本
- properties["quartz.dataSource.myDS.provider"] = "SqlServer-20";
- //最大链接数
- //properties["quartz.dataSource.myDS.maxConnections"] = "5";
- // First we must get a reference to a scheduler
- ISchedulerFactory sf = new StdSchedulerFactory(properties);
- IScheduler sched = sf.GetScheduler();

上面便是创建一个调度器,以及配置与quartz数据库的详细参数。有啦数据库后你会很兴奋,直接写t-sql操作数据库多么便捷啊,并且所有的任务调度信息都一目了然,这里我要告诉你的事,你不需要直接写sql语句,quart提供的类库就能自动对数据库进行填充,以完成对任务调度的管理操作。
quartz.net任务调度的各种操作方法
首先我要说下,我前面有一篇文章对quartz.net做个基本的操作描述,这里也只贴代码,仅供参考。
1、添加任务计划,并制定要触发的执行类

- #region 检查是否存在
- if (IsExistJob(m.JobGroupName, m.JobName))
- {
- return false;
- }
- #endregion
- #region 添加任务计划
- if (m.StarTime == null)
- {
- m.StarTime = DateTime.Now;
- }
- DateTimeOffset starRunTime = DateBuilder.NextGivenSecondDate(m.StarTime, 1);
- if (m.EndTime == null)
- {
- m.EndTime = DateTime.MaxValue.AddDays(-1);
- }
- DateTimeOffset endRunTime = DateBuilder.NextGivenSecondDate(m.EndTime, 1);
- scheduler = GetScheduler();
- IJobDetail job = JobBuilder.Create<QuartzFunction>()
- .WithIdentity(m.JobName, m.JobGroupName)
- .WithDescription(m.JobDescribe)
- .Build();
- ICronTrigger trigger = (ICronTrigger)TriggerBuilder.Create()
- .StartAt(starRunTime)
- .EndAt(endRunTime)
- .WithIdentity(m.JobName, m.JobGroupName)
- .WithCronSchedule(m.CronStr)
- .WithDescription(m.JobDescribe)
- .Build();
- scheduler.ScheduleJob(job, trigger);
- scheduler.Start();
- #endregion
- #region 关联运行接口
- var api = new A_RunJobTriggerEntity();
- api.ApiCode = m.ApiCode;
- api.ApiType = m.ApiType;
- api.ApiUrl = m.ApiUrl;
- api.AppID = m.AppID;
- api.CreateTime = DateTime.Now;
- api.JobDescribe = m.JobDescribe;
- api.ServiceCode = m.ServiceCode;
- api.Token = m.Token;
- api.TriggerGroup = m.JobGroupName;
- api.TriggerName = m.JobName;
- new ARunJobRelationManage().Insert(api);
- #endregion

2、移除执行计划
- scheduler = GetScheduler();
- var trigger = new TriggerKey(jobGroup, jobName);
- scheduler.PauseTrigger(trigger);//停止触发器
- scheduler.UnscheduleJob(trigger); //移除触发器
- var result = scheduler.DeleteJob(JobKey.Create(jobName,jobGroup));
3、暂停指定任务计划
- scheduler = GetScheduler();
- scheduler.PauseJob(JobKey.Create(jobName, jobGroup));
4、暂停所有的任务计划
- scheduler = GetScheduler();
scheduler.PauseAll();
5、开启指定的任务计划

- scheduler = GetScheduler();
- if (!scheduler.IsStarted)
- {
- scheduler.Start();
- }
- //scheduler.ResumeTrigger(new TriggerKey(jobName, jobGroup));
- scheduler.ResumeJob(JobKey.Create(jobName, jobGroup));

6、开启所有的任务计划

- scheduler = GetScheduler();
- if (!scheduler.IsStarted)
- {
- scheduler.Start();
- }
- //scheduler.ResumeTrigger(new TriggerKey(jobName, jobGroup));
- scheduler.ResumeAll();

7、调度启动状态,如果调度的状态没有开启,即便触发器的状态为等待执行,执行中,也是无效的。

- scheduler = GetScheduler();
- if (scheduler.IsStarted)
- {
- return "开启";
- }
- else
- {
- return "关闭";
- }

8、是否集群
- //是否集群
- //properties["quartz.jobStore.clustered"] = "false";
- //properties["quartz.scheduler.instanceId"] = "AUTO";
检验下结果:
我在两台服务器上部署,设置一个任务计划,每2秒出发一次,2台机器同时跑,没有重复执行,且一台服务器down掉仍可准确无误的运行,给图。
总结
如果你在用quartz.net中有什么疑惑,或者有什么好的项目分享,欢迎加入右上角的群,我们一起学习进步。
t持久化与集群部署开发详解的更多相关文章
- Quartz.net持久化与集群部署开发详解
序言 我前边有几篇文章有介绍过quartz的基本使用语法与类库.但是他的执行计划都是被写在本地的xml文件中.无法做集群部署,我让它看起来脆弱不堪,那是我的罪过. 但是quart.net是经过许多大项 ...
- 2、Redis 底层原理:Cluster 集群部署与详解
Redis 简介 Redis 提供数据缓存服务,内部数据都存在内存中,所以访问速度非常快. 早期,Redis 单应用服务亦能满足企业的需求.之后,业务量的上升,单机的读写能力满足不了业务的需求,技术上 ...
- 深入浅出—Redis集群的相关详解
前言: 这篇文章主要介绍了Redis集群的相关,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值. 注意!要求使用的都是redis3.0以上的版本,因为3.0以上增加了red ...
- hadoop1.2.1+zk-3.4.5+hbase-0.94.1集群安装过程详解
hadoop1.2.1+zk-3.4.5+hbase-0.94.1集群安装过程详解 一,环境: 1,主机规划: 集群中包括3个节点:hadoop01为Master,其余为Salve,节点之间局域网连接 ...
- 高可用,多路冗余GFS2集群文件系统搭建详解
高可用,多路冗余GFS2集群文件系统搭建详解 2014.06 标签:GFS2 multipath 集群文件系统 cmirror 实验拓扑图: 实验原理: 实验目的:通过RHCS集群套件搭建GFS2集群 ...
- [转]Hadoop集群_WordCount运行详解--MapReduce编程模型
Hadoop集群_WordCount运行详解--MapReduce编程模型 下面这篇文章写得非常好,有利于初学mapreduce的入门 http://www.nosqldb.cn/1369099810 ...
- redis cluster 集群 安装 配置 详解
redis cluster 集群 安装 配置 详解 张映 发表于 2015-05-01 分类目录: nosql 标签:cluster, redis, 安装, 配置, 集群 Redis 集群是一个提供在 ...
- 大数据学习系列之七 ----- Hadoop+Spark+Zookeeper+HBase+Hive集群搭建 图文详解
引言 在之前的大数据学习系列中,搭建了Hadoop+Spark+HBase+Hive 环境以及一些测试.其实要说的话,我开始学习大数据的时候,搭建的就是集群,并不是单机模式和伪分布式.至于为什么先写单 ...
- Linux 高可用(HA)集群之keepalived详解
http://freeloda.blog.51cto.com/2033581/1280962 大纲 一.前言 二.Keepalived 详解 三.环境准备 四.LVS+Keepalived 实现高可用 ...
随机推荐
- nginx+tomcat负载均衡策略
測试环境均为本地,測试软件为: nginx-1.6.0,apache-tomcat-7.0.42-1.apache-tomcat-7.0.42-2.apache-tomcat-7.0.42-3 利用n ...
- Oracle12C 怎样导入scott用户
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaG9uZ2thbmd3bA==/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...
- SQL Server定时自动抓取耗时SQL并归档数据脚本分享
原文:SQL Server定时自动抓取耗时SQL并归档数据脚本分享 SQL Server定时自动抓取耗时SQL并归档数据脚本分享 第一步建库 USE [master] GO CREATE DATABA ...
- 斯坦福ML公开课笔记15—隐含语义索引、神秘值分解、独立成分分析
斯坦福ML公开课笔记15 我们在上一篇笔记中讲到了PCA(主成分分析). PCA是一种直接的降维方法.通过求解特征值与特征向量,并选取特征值较大的一些特征向量来达到降维的效果. 本文继续PCA的话题, ...
- EXPORT_SYMBOL解析
一般我们编写C程序时,要调用某个文件中的函数,需要在本文件中包含声明有被调用函数的头文件,然后编译连接后,方能找到调用函数.对于模块依赖的情况,不能简单的使用上面的方法,内核提供了一个机制,就是EXP ...
- iOS得知1_初体验
UIView:父类的所有控件,所有的UIView它是一个容器.可容纳其他UIView UIController:用于控制UIView,责创建/销毁自己的UIView,显示/隐藏UIView.处理UIV ...
- 【译】ASP.NET MVC 5 教程 - 7:Edit方法和Edit视图详解
原文:[译]ASP.NET MVC 5 教程 - 7:Edit方法和Edit视图详解 在本节中,我们继续研究生成的Edit方法和视图.但在研究之前,我们先将 release date 弄得好看一点.打 ...
- poj1947(树形dp)
题目链接:http://poj.org/problem?id=1947 题意:给n(n<=150)个点的一棵树,求删掉最少边数k使得最后该树只剩下p(1<=p<=n)个节点.(求最小 ...
- java设计模式_单例
public class Singleton { public static void main(String[] args) throws Exception { System.out.printl ...
- Linux下SVN账户密码保存设置
Linux下用SVN进行更新等操作时,总是提示输入用户名和密码,很不方便.因此搜了下解决办法,总结如下: 打开SVN配置文件: vim /home/<user>/.subversion/c ...