[ay的quartz.net 学习笔记[4/5]

2017-11-12

在实际使用quartz.net中,持久化能保证实例重启后job不丢失、 集群能均衡服务器压力和解决单点问题。

quartz.net在这两方面配置都比较简单

quartz.net的持久化,是把job、trigger一些信息存储到数据库里面,以解决内存存储重启丢失

这里用了别人的一个开源项目,搭建起来吧,代码值得研究看看。

地址: https://github.com/quartznet/quartznet

创建库

USE [master]
GO
/****** 对象:  Database  [AyQZ]   脚本日期:  ******/
CREATE DATABASE [AyQZ] ON  PRIMARY 
( NAME = N'QP_AyQZ', FILENAME = N'D:AyQZ.mdf' , SIZE = 8192KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
 LOG ON 
( NAME = N'QP_AyQZ_log', FILENAME = N'D:AyQZ_log.ldf' , SIZE = 2048KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
GO

然后再执行那个脚本文件

QRTZ_BLOB_TRIGGERS  以Blob 类型存储的触发器。

QRTZ_CALENDARS   存放日历信息, quartz.net可以指定一个日历时间范围。

QRTZ_CRON_TRIGGERS  cron表达式触发器。

QRTZ_JOB_DETAILS      job详细信息。

QRTZ_LOCKS       集群实现同步机制的行锁表

QRTZ_SCHEDULER_STATE   实例信息,集群下多使用。

如上是上面的那个demo的sql,我发现他的demo我编译不过啊。。

于是我又只能瞎折腾,我找到官网下载的最新的2.6.1,试着找脚本,因为这里肯定是配套的嘛。

我删除了库,用当前版本的sql创建。

USE [master]
GO
/****** 对象:  Database [AyQZ]    脚本日期: 11/10/2017 16:38:08 ******/
if exists(select * from dbo.sysdatabases where name='[AyQZ]')  

    drop database [AyQZ]  

GO  
CREATE DATABASE [AyQZ] ON  PRIMARY 
( NAME = N'QP_AyQZ', FILENAME = N'D:AyQZ.mdf' , SIZE = 8192KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
 LOG ON 
( NAME = N'QP_AyQZ_log', FILENAME = N'D:AyQZ_log.ldf' , SIZE = 2048KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
GO

客户端代码修改如下:你只需要改数据库连接字符串

  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"] = @"Data Source=(local);Initial Catalog=AyQZ;User ID=sa;Password=123123";
            //sqlserver版本
            properties["quartz.dataSource.myDS.provider"] = "SqlServer-20";

            var schedulerFactory = new StdSchedulerFactory(properties);
            var scheduler = schedulerFactory.GetScheduler();

            var job = JobBuilder.Create<HelloJob>()
                .WithIdentity("myJob", "group1")
                .Build();

            var trigger = TriggerBuilder.Create()
                                .WithIdentity("mytrigger", "group1")
                                .WithCronSchedule("/2 * * ? * *")
                                .Build();

            scheduler.ScheduleJob(job, trigger);
            scheduler.Start();

运行后,发现QRTZ_CRON_TRIGGERS表和QRTZ_FIRED_TRIGGERS有数据了。

1: 持久化后,job只有添加一次了(数据库已经有了),所以不能再执行端写添加job的行为。这时候需要一个管理工具,动态添加操作。

2: quartz.net 支持sql server、sqlite、mysql、oracle、mongodb(非官方版)。

如图quartz.net 的集群模式是依赖数据库表的,所以要持久化配置。  集群节点之间是不通信的,这样分布式的架构,很方便进行水平扩展。

1: 除了线程池数量,instanceId可以不同外,各个节点的配置必须是一样的。

2:集群中节点的系统时间一致。

3:多线程、集群中。quartz.net 利用数据库锁来保证job不会重复执行。

源码在DBSemaphore.cs、UpdateLockRowSemaphore.cs、StdRowLockSemaphore.cs

4:集群化后,某节点失效后,剩余的节点能保证job继续执行下去。

实例配置后启动。

properties["quartz.jobStore.clustered"] = "true";

properties["quartz.scheduler.instanceId"] = "AUTO";

好了,官方的DEMO还不知道怎么启动起来,学到这里了,我感觉到了,任务Task这块  需要两种客户端管理,一种普通的,上次那个,还有个是集群方式的管理。

这些C#应该有几个开源的吧。如果没有可以参考,学习自己写一个。

====================www.ayjs.net       杨洋    wpfui.com        ayui      ay  aaronyang=======请不要转载谢谢了。=========

竟然说到管理这块,估计很多人要把这些集成到自己的系统,也就是二次开发了。

也就是感觉  增删改查job,trigger什么的了。启动,暂停服务。

添加Job

第一种,传统,继承IJob然后 用CrystalQuartz,或者自己写个管理  任务。

第二种反射:定义个接口,自己设计,所有的job继承它,然后上传到服务器某个文件夹,重新反射获得所有任务。

interface IcustomJob

{

void Excute(string context);

void Failed(string error);

void Complete(string msg);

}

类似插件,这样又有新任务了。

第三种,执行uri的任务,一个通用的http的任务管理器,你加HTTP地址进去,指定是get还是post的方式去执行。

同理,你也可以 获得 字符串,自己分析,执行 进程任务。

Process p = new Process();

p.StartInfo.UseShellExecute = true;

p.StartInfo.FileName = jd.Path;

p.StartInfo.Arguments = jd.Parameters;   //空格分割

p.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;

p.Start();

public class HttpJob : IJob
    {
        public void Execute(IJobExecutionContext context)
        {
            var dataMap = context.JobDetail.JobDataMap;

            var content = dataMap.GetString("jobData");

            var jd = new JavaScriptSerializer().Deserialize<HttpJobData>(content);

            if (jd.Parameters == null)
                jd.Parameters = string.Empty;
            if (jd.Timeout == 0)
                jd.Timeout = 5*60;

            var result = RequestHelper.Post(jd.Url, jd.ContentType, jd.Timeout, jd.Parameters, jd.heads);
        }
    }

请求URL时,注意双方约定token加密,防止非执行节点执行调用。

使用方,如果有耗时操作,建议异步执行。

最后1个,自己写框架,管理job,比如CrystalQuartz这个,当然还有官网提供的集群方式。

www.ayjs.net 六安杨洋(AY)拓展

所以Ay,接下来任务,要写个  客户端 exe方式的 管理 job和trigger

====================www.ayjs.net       杨洋    wpfui.com        ayui      ay  aaronyang=======请不要转载谢谢了。=========

推荐您阅读更多有关于“”的文章


用户评论
开源开发学习小组列表