当前位置:网站首页 / C#人爱学不学 / 正文

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

时间:2017年11月10日 | 作者 : aaronyang | 分类 : C#人爱学不学 | 浏览: 635次 | 评论 0

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

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

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

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

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

blob.png

创建库

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

然后再执行那个脚本文件

blob.png

  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,试着找脚本,因为这里肯定是配套的嘛。

blob.png

我删除了库,用当前版本的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有数据了。

blob.png

blob.png

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

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


blob.png

如图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=======请不要转载谢谢了。=========






JobStore负责保持对所有scheduler “工作数据”追踪,这些工作数据包括:job(任务),trigger(触发器),calendar(日历)等。为你的Quartz scheduler选择合适的JobStore是非常重要的一步,幸运的是,如果你理解了不同的JobStore之间的差别,那么选择就变得非常简单。在提供产生scheduler 实例的SchedulerFactory的属性文件中声明scheduler所使用的JobStore(以及它的配置)。

注:不要在代码中直接使用JobStore实例,处于某些原因,很多人试图这么做。JobStore是由Quartz自身在幕后使用。你必须告诉(通过配置)Quartz使用哪个JobStore,而你只是在你的代码中使用Scheduler接口完成工作。

RAMJobStore


RAMJobStore是最简单的JobStore,也是性能最好的(根据CPU时间)。从名字就可以直观地看出,RAMJobStore将所有的数据都保存在RAM中。这就是为什么它闪电般的快速和如此容易地配置。缺点就是当应用结束时所有的日程信息都会丢失,这意味着RAMJobStore不能满足Jobs和Triggers的持久性(“non-volatility”)。对于有些应用来说,这是可以接受的,甚至是期望的行为。但是对于其他应用来说,这将是灾难。

为了使用RAMJobStore(假设你使用DirectSchedulerFactory),指使简单地将类名Quartz.Simpl.RAMJobStore作为你的quartz的配置值。

配置 Quartz 使用 RAMJobStore

<quartz>

         <add key="quartz.jobStore.type" value="Quartz.Simpl.RAMJobStore, Quartz" />

</quartz>

这里没有其他需要的担心的配置。 Qiartz.net缺省使用的就是RAMJobStore.

ADO.NET Job Store (AdoJobStore)

基于ADO.NET的 job store 目前正在开发中,还存在很多的bug. 从0.6版本开始

AdoJobStore基本上可以用了.

AdoJobStore的命名也非常得体,它将所有的数据通过ADO.NET保存到数据库可中。它的配置要比RAMJobStore稍微复杂,同时速度也没有那么快。但是性能的缺陷不是非常差,尤其是如果你在数据库表的主键上建立索引。

AdoJobStore几乎可以在任何数据库上工作,它广泛地使用Oracle, MySQL, MS SQLServer2000, HSQLDB, PostreSQL 以及 DB2。要使用AdoJobStore,首先必须创建一套Quartz使用的数据库表,可以在Quartz 的database\tables找到创建库表的SQL脚本。如果没有找到你的数据库类型的脚本,那么找到一个已有的,修改成为你数据库所需要的。需要注意的一件事情就是所有Quartz库表名都以QRTZ_作为前缀(例如:表"QRTZ_TRIGGERS",及"QRTZ_JOB_DETAIL")。实际上,可以你可以将前缀设置为任何你想要的前缀,只要你告诉AdoJobStore那个前缀是什么即可(在你的Quartz属性文件中配置)。对于一个数据库中使用多个scheduler实例,那么配置不同的前缀可以创建多套库表,十分有用。

一旦数据库表已经创建,在配置和启动AdoJobStore之前,就需要作出一个更加重要的决策。你要决定在你的应用中需要什么类型的事务。如果不想将scheduling命令绑到其他的事务上,那么你可以通过对JobStore使用JobStoreTX来让Quartz帮你管理事务(这是最普遍的选择)。

最后的疑问就是如何建立获得数据库联接的数据源(DataSource)。Quartz属性中定义数据源是通过提供所有联接数据库的信息,让Quartz自己创建和管理数据源。

要使用AdoJobStore(假定使用StdSchedulerFactory),首先需要设置Quartz配置中的quartz.jobStore.type属性为Quartz.Impl.AdoJobStore.JobStoreTX, Quartz。

配置 Quartz使用 JobStoreTx

quartz.threadPool.type = Quartz.Simpl.SimpleThreadPool, Quartz

下一步,需要为JobStore 选择一个DriverDelegate , DriverDelegate负责做指定数据库的所有ADO.NET工作。StdADO.NETDelegate是一个使用vanilla" ADO.NET代码(以及SQL语句)来完成工作的代理。如果数据库没有其他指定的代理,那么就试用这个代理。只有当使用StdADO.NETDelegate发生问题时,我们才会使用数据库特定的代理(这看起来非常乐观。其他的代理可以在Quartz.Impl.AdoJobStor命名空间找到。)。其他的代理包括PostgreSQLDelegate ( 专为PostgreSQL 7.x)。

一旦选择好了代理,就将它的名字设置给AdoJobStore。

配置AdoJobStore 使用DriverDelegate

quartz.threadPool.type = Quartz.Simpl.SimpleThreadPool, Quartz

接下来,需要为JobStore指定所使用的数据库表前缀(前面讨论过)。

配置AdoJobStore的数据库表前缀

quartz.jobStore.tablePrefix = QRTZ

然后需要设置JobStore所使用的数据源。必须在Quartz属性中定义已命名的数据源,比如,我们指定Quartz使用名为"default"的数据源(在配置文件的其他地方定义)。

配置 AdoJobStore使用数据源源的名字

properties["quartz.jobStore.dataSource"] = "default"

   最后,需要配置数据源的使用的Ado.net数据提供者和数据库连接串,数据库连接串是标准的Ado.net 数据库连接的连接串。数据库提供者是关系数据库同Quartz.net之间保持低耦合的数据库的连接提供者。

配置AdoJobStore使用数据源源的数据库连接串和数据库提供者

quartz.dataSource.default.connectionString = Server=(local);Database=quartz;Trusted_Connection=True;

quartz.dataSource.default.provider= SqlServer-11

   目前Quartz.net支持的以下数据库的数据提供者:

SqlServer-11 - SQL Server driver for .NET Framework 1.1

SqlServer-20 - SQL Server driver for .NET Framework 2.0

OracleClient-20 - Microsoft's Oracle Driver (comes bundled with .NET Framework)

OracleODP-20 - Oracle's Oracle Driver

MySql-10 - MySQL Connector/.NET v. 1.0.7

MySql-109 - MySQL Connector/.NET v. 1.0.9

MySql-50 - MySQL Connector/.NET v. 5.0 (.NET 2.0)

MySql-51 - MySQL Connector/:NET v. 5.1 (.NET 2.0)

SQLite1044 - SQLite ADO.NET 2.0 Provider v. 1.0.44 (.NET 2.0)

如果Scheduler非常忙(比如,执行的任务数量差不多和线程池的数量相同,那么你需要正确地配置DataSource的连接数量为线程池数量。为了指示AdoJobStore所有的JobDataMaps中的值都是字符串,并且能以“名字-值”对的方式存储而不是以复杂对象的序列化形式存储在BLOB字段中,应设置 quartz.jobStore.useProperties配置参数的值为"true"(这是缺省的方式)。这样做,从长远来看非常安全,这样避免了对存储在BLOB中的非字符串的序列化对象的类型转换问题。








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

猜你喜欢

额 本文暂时没人评论 来添加一个吧

发表评论

必填

选填

选填

必填

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

  查看权限

作者:杨洋(AaronYang简称AY,安徽六安人)目前是个人,还没成立公司AY唯一QQ:875556003和AY交流

高中学历,2015年1月17日开始,兴趣学习研究WPF

声明:AYUI个人与商用免费,源码可购买。部分DEMO不免费

查看捐赠

AYUI7.X MVC教程 更新如下:

第一课 第二课 程序加密教程

兼容XP到win10,vs2015/2017,最新AYUI:7.6.2.8

一次购买,永久免费更新,bug反馈及时修复,普通话回答你的问题,3个月的技术支持

AYUI7.6.X 企业服务详情:680元

AYUI7.6.X 官方风格详情:4000元

AYUI7.6.X 医疗+官方风格详情5000元

本AYUI知识版权最终归杨洋(AY)所有

本AYUI最终销售权归杨洋(AY)所有

vs2015 企业版密钥HM6NR-QXX7C-DFW2Y-8B82K-WTYJV

vs2017 企业版密钥NJVYC-BMHX2-G77MM-4XJMR-6Q8QF

标签列表