.NetCore中使用作业调度

我们总是会遇到这样的业务,

1、监测会员卡是否到期了

2、监测我们服务器的CPU使用情况,硬盘以及内存的占用情况

3、悄悄的将用户数据同步至另外一台服务器

一旦遇到这种情况,我理所应当想到Windows服务。

作为一个合格的开发人员,我怎么可以一直保持固有想法,渐渐的发现Windows服务的各种弊端跟缺陷

1、明明我们的业务系统已经停止使用了,但是开发人员忘记了停止并卸载Windows服务,导致服务器上有很多无效windows服务,白白浪费着服务器性能

2、我们用时候遇到跟支付宝以及微信推送支付消息相同的业务,支付完成后,马上推送一次请求端,1分钟,3分钟,5分钟...半小时各推送一次,直至客户端返回Scuess,我们才停止推送,这样的推送方式,导致我们在写Window服务时,徒增很多困难。

我们安于现状,不需求改变,明知有各种弊端,但是我们一旦遇到困难,总是想从最简单的方式开始入手,寻求解决方案。

突然有一天,我们的Boss在开完晨会后,

跟我说,.NetCore已经支持跨平台了,是不是?

我马上回答,是,这扬眉吐气,搞Java的Diss搞C#开发的这么多年,不就是因为不跨平台么

我们Boss说,好,从现在开始,为了节省成本,我们现有的业务系统迁移至linux服务器。

万万没想到,我仅仅一个是,跟我们项目组带来这么大麻烦。

老板看我犹豫,问我,跨平台迁移有困难?

我咬着牙说,没有,就算咬碎了牙也不能立马打脸啊

windows迁移linux,对于一个linux小白来说,遇到了很多困难,这些困难以及坑我会在后续的文章中,慢慢跟大家分享。今天着重说一下Windows服务。

我遇到的第一个问题就是,我们的用于监测业务数据的Window服务怎么办?

linux可不能随随便便就部署一个Windows服务

一次找资料中无意间看到任务调度框架,任务调度框架,可以完美解决我们的Windows服务问题

任务调度框架的开源代码有很多,在众多框架中找到了Quartz,救命稻草

废话不多说,直接上代码,毕竟关于Quartz,很多大神已经写了很多代码

我们只需要在程序启动的过程中加入任务调度框架即可,在代码:

     public void Configure(IApplicationBuilder app, IHostingEnvironment env)
     {
           #region 创建作业调度
           RunProgram().GetAwaiter().GetResult();
           #endregion
     }

ok,剩下我们就需要在RunProgram方法中配置我们的作业调度框架信息

我的代码如下:

       #region 创建微信消息推送任务调度
            /// <summary>
            /// 创建微信消息推送任务调度
            /// </summary>
            /// <returns></returns>
            private static async Task RunProgram()
            {
                try
                {
                    // Grab the Scheduler instance from the Factory
                    NameValueCollection props = new NameValueCollection
                    {
                        { "quartz.serializer.type", "binary" }
                    };
                    StdSchedulerFactory factory = new StdSchedulerFactory(props);
                    IScheduler scheduler = await factory.GetScheduler();
     
     
     
                    IJobDetail job = JobBuilder.Create<WeChatAuthMessagePush>()
                        .WithIdentity("jobPushWeChatAuthMessage", "groupWeChatAuth")
                        .Build();
     
                    ISimpleTrigger trigger = (ISimpleTrigger)TriggerBuilder.Create()
                        .WithIdentity("triggerPushWeChatAuthMessage", "groupWeChatAuth")
                        .StartNow().WithSimpleSchedule(x => x.WithIntervalInMinutes(10).RepeatForever()).Build();
     
                    await scheduler.ScheduleJob(job, trigger);
     
                    // and start it off
                    await scheduler.Start();
                    // some sleep to show what's happening
                    //await Task.Delay(TimeSpan.FromSeconds(3));
     
                    // and last shut down the scheduler when you are ready to close your program
                    //await scheduler.Shutdown();
                }
                catch (SchedulerException se)
                {
                    await Console.Error.WriteLineAsync(se.ToString());
                }
            }
            #endregion

下面我一一介绍一下,这些参数的意思,也方便自己加深记忆

IScheduler:调度器。所有的调度都是由它控制。

Trigger: 定义触发的条件。例子中,它的类型是SimpleTrigger,每隔10分钟执行一次

JobDetail & Job: JobDetail 定义的是任务数据,而真正的执行的业务代码是在Job中,例子中是WeChatAuthMessagePush。 为什么设计成JobDetail + Job,不直接使用Job?这是因为任务是有可能并发执行,如果Scheduler直接使用Job,就会存在对同一个Job实例并发访问的问题。而JobDetail & Job 方式,sheduler每次执行,都会根据JobDetail创建一个新的Job实例,这样就可以规避并发访问的问题。

ok,下一步,我们的作业调度方法继承自IJob接口,实现IJob接口中的Execute方法,Execute方法中即可以处理我们的业务计划。

代码如下:

    ​
     public async Task Execute(IJobExecutionContext context)
     {
                
        await Console.Out.WriteLineAsync("任务计划调度成功!");
     }
        
     
    ​

我们看一下接口IJobExecutionContext中的方法以及参数

    //
        // 摘要:
        //     A context bundle containing handles to various environment information, that
        //     is given to a Quartz.IJobExecutionContext.JobDetail instance as it is executed,
        //     and to a Quartz.ITrigger instance after the execution completes.
        public interface IJobExecutionContext
        {
            //
            // 摘要:
            //     Get the Quartz.IJobExecutionContext.JobDetail associated with the Quartz.IJob.
            IJobDetail JobDetail { get; }
            
        }

我们针对这些参数一一解释

在JobDetail中,我们可以获取作业调度框架的详细信息以及描述信息,如:

context.JobDetail.Key.Group

context.JobDetail.Key.Name
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值