net core WebApi-- regular tasks Quartz

Foreword

Was going to have to start writing this yesterday, because of the small team should organize the blog summary, a look at two of Kazakhstan's blog so much, certainly one copy and paste trouble (in fact, I feel replicate trouble), so interspersed with writing small reptiles, after writing almost took them out to air dry it (py chicken dish level).

Prior to the development time, ignoring the record, until the time to write a little something about what's with the background, have a little bit of memory, because a colleague recently said to me, "hey, give me a monthly statistical data do a display interface ah. " I do not think a month headache operations, Hey, no, this is not to write a regular task to get citizenship.

Quartz

In fact, in this election timer library when I was in Hangfire between them wander, and later thought Regardless of the method what tools are secondary, mainly to see how you use, where to use, graphical interface is required but is not necessary, minute and second levels of control are also on your own business needs, the timer runs backstage to hang on the line no need to let me see, want to operate talk about it, it is so pleasant decided to use the Quartz .

First, the introduction of the package is still in our Util project.

After the introduction is complete, add the registration statement instance in our entrance in Startup.

        public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            ServiceInjection.ConfigureRepository(services);

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
            //任务调度
            services.TryAddSingleton<ISchedulerFactory, StdSchedulerFactory>();
        }

SchedulerFactory task scheduler is like a company boss, the Trigger is a tubular item, the Job is hard to force the code of agriculture, the boss wants to one day put forward app, just like the term tube to say, I want to stuff the day after, this time of possession there are a few heart, after that time of the day, find the code farmers, deprived of his direct code execution, a good app out, hard to force the end really does not mean the end, which saw the boss can ah, well, after a day I'll have a finished app, so the cycle of possession patiently, farm yards for another change (of course, not job).

There will be a plurality of pipe entry, each entry below the tube can be more than one yard farming.

Like this situation may be somewhat exaggerated, but a similar situation was real.

ok, after the expiry of, let's create a MyJob .

    public class MyJob : IJob
    {
        public Task Execute(IJobExecutionContext context)
        {
            return Task.Run(() =>
            {
                LogUtil.Debug("执行MyJob");
            });
        }
    }

Then we write a simple QuartzUtil .

    public class QuartzUtil
    {
        private static ISchedulerFactory _schedulerFactory;
        private static IScheduler _scheduler;

        /// <summary>
        /// 添加任务
        /// </summary>
        /// <param name="type">类</param>
        /// <param name="jobKey">键</param>
        /// <param name="trigger">触发器</param>
        public static async void Add(Type type, JobKey jobKey, ITrigger trigger = null)
        {
            Init();
            _scheduler = await _schedulerFactory.GetScheduler();

            await _scheduler.Start();

            if (trigger == null)
            {
                trigger = TriggerBuilder.Create()
                    .WithIdentity("april.trigger")
                    .WithDescription("default")
                    .WithSimpleSchedule(x=>x.WithMisfireHandlingInstructionFireNow().WithRepeatCount(-1))
                    .Build();
            }
            var job = JobBuilder.Create(type)
                .WithIdentity(jobKey)
                .Build();

            await _scheduler.ScheduleJob(job, trigger);          
        }
        /// <summary>
        /// 恢复任务
        /// </summary>
        /// <param name="jobKey">键</param>
        public static async void Resume(JobKey jobKey)
        {
            Init();
            _scheduler = await _schedulerFactory.GetScheduler();
            LogUtil.Debug($"恢复任务{jobKey.Group},{jobKey.Name}");
            await _scheduler.ResumeJob(jobKey);
        }
        /// <summary>
        /// 停止任务
        /// </summary>
        /// <param name="jobKey">键</param>
        public static async void Stop(JobKey jobKey)
        {
            Init();
            _scheduler = await _schedulerFactory.GetScheduler();
            LogUtil.Debug($"暂停任务{jobKey.Group},{jobKey.Name}");
            await _scheduler.PauseJob(jobKey);
        }
        /// <summary>
        /// 初始化
        /// </summary>
        private static void Init()
        {
            if (_schedulerFactory == null)
            {
                _schedulerFactory = AprilConfig.ServiceProvider.GetService<ISchedulerFactory>();
            }
        }
    }

Using triggers, there are many ways you can use to perform a simple / long execution time / cycle performed several times, and so on.

There you can use Cron expression:

In simple terms, Corn from left to right (separated by spaces): second minute hour day of the month month week of the date of the year , for example, as said at the beginning, let me once every month or execution statistics, writing is 0001 *?, which of course there are issues related to what the symbols, and this does not need to memorize, when required under investigation on the line, it is recommended a tool station, Cron verification tool .

test

I feel good blog content monotonous, content framework that is beginning, code, test, ending, alas

But things Zuosa, test and ultimately, the most basic thing you can only viable explanation.

We Values add a method, where we perform a 5s (too lazy, etc.).

        [HttpGet]
        [Route("QuartzTest")]
        public void QuartzTest(int type)
        {
            JobKey jobKey = new JobKey("demo","group1");
            switch (type)
            {
                //添加任务
                case 1:
                    var trigger = TriggerBuilder.Create()
                            .WithDescription("触发器描述")
                            .WithIdentity("test")
                            //.WithSchedule(CronScheduleBuilder.CronSchedule("0 0/30 * * * ? *").WithMisfireHandlingInstructionDoNothing())
                            .WithSimpleSchedule(x=>x.WithIntervalInSeconds(5).RepeatForever().WithMisfireHandlingInstructionIgnoreMisfires())
                            .Build();
                    QuartzUtil.Add(typeof(MyJob), jobKey, trigger);
                    break;
                //暂停任务
                case 2:
                    QuartzUtil.Stop(jobKey);
                    break;
                //恢复任务
                case 3:
                    QuartzUtil.Resume(jobKey);
                    break;
            }
        }

Let's happy to run it, remember appsettings configure access paths white list.

test

After some input 1,2,3 finished, we look at the log.
test

  • Mission --- ok
  • Pause task --- ok
  • Recovery tasks --- ok

Problems and Solutions

But the question arises, after a pause resume, and even executed many times (see specific time interval you and your frequency), this is kinda weird, I remember this question let me tinker for ages, but also a variety of search to find information method, but actually it is this protective mechanism Quartz, in order to prevent your operation because of problems caused by unpredictable, so there is a redo missed task, and our code triggers also have this configuration WithMisfireHandlingInstructionIgnoreMisfires .

Let's get rid of this mechanism and redo the test.

test

CronTrigger

rule Introduction
withMisfireHandlingInstructionDoNothing Does not trigger immediate execution; waiting for the next trigger frequency Cron arrival time sequentially executed in accordance with the frequency Cron
withMisfireHandlingInstructionIgnoreMisfires The first time at a frequency of missed start right away; redo all frequencies missed period; the current time is greater than the frequency of the current time once triggered, in turn accordance with normal frequency Cron
withMisfireHandlingInstructionFireAndProceed The current time as the trigger frequency immediately trigger the first performance; and are executed in the frequency Cron

SimpleTrigger

rule Introduction
withMisfireHandlingInstructionFireNow The current time as a trigger to trigger immediate execution frequency; to the remaining number of execution cycles FinalTIme; or to schedule a time for recovery scheduling cycle frequency reference, FinalTime calculated based on the remaining number of times and the current time; FinalTime slightly greater than the adjusted according starttime the calculated value to FinalTime
withMisfireHandlingInstructionIgnoreMisfires The first time at a frequency of missed start right away; redo all frequencies missed period; the next time the trigger is greater than the frequency of the current time after time, in order to perform in accordance with Interval of the remaining frequency; total execution RepeatCount + 1 times
withMisfireHandlingInstructionNextWithExistingCount Does not trigger an immediate execution; wait for the next trigger frequency cycle time, to perform the number of remaining cycles FinalTime; startTime to calculate the reference cycle frequency, and obtain FinalTime; FinalTime remains unchanged even if the intermediate time occurs pause, resume after
withMisfireHandlingInstructionNowWithExistingCount The current time as a trigger to trigger immediate execution frequency; to the remaining number of execution cycles FinalTIme; or to schedule a time for recovery scheduling cycle frequency reference, FinalTime calculated based on the remaining number of times and the current time; FinalTime slightly greater than the adjusted according starttime the calculated value to FinalTime
withMisfireHandlingInstructionNextWithRemainingCount Does not trigger an immediate execution; wait for the next trigger frequency cycle time, to perform the number of remaining cycles FinalTime; startTime to calculate the reference cycle frequency, and obtain FinalTime; FinalTime remains unchanged even if the intermediate time occurs pause, resume after
withMisfireHandlingInstructionNowWithRemainingCount The current time as a trigger to trigger immediate execution frequency; to the remaining number of execution cycles FinalTIme; or to schedule a time for recovery scheduling cycle frequency reference, FinalTime calculated based on the remaining number of times and the current time; FinalTime slightly greater than the adjusted according starttime the calculated value to FinalTime

Configure rules Introduction Reference: https://blog.csdn.net/yangshangwei/article/details/78539433

Before meeting in net framework had a problem, IIS recycling issues, the site after 20 minutes of non-stop requests, task followed stopped, then the solution is to be a windows service to regular site requests remain active, of course, You can also keep the site has been run by prohibiting recycling.

net core in the deployment have not run if there are related issues, follow-up will add up together to solve the exchange.

summary

Regular tasks generally used in a scene fairly extensive back-end systems, mainly sql statistics, sql / file backup, timed push, etc., to analyze specific issues, NET Core 3.0 have already come out, life-long learning ah.

Guess you like

Origin www.cnblogs.com/AprilBlank/p/11595603.html