In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly explains "what is the use of Quartz.Net". Friends who are interested may wish to have a look at it. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn "what is the use of Quartz.Net?"
During the development of the project, you will inevitably encounter tasks that need to be processed in the background, such as regularly sending email notifications, time-consuming data processing, and so on. At this time, you need Quartz.Net.
Quartz.Net is pure, it is a .net assembly and is a C # implementation of the very popular Java job scheduling system Quartz.
Quartz.Net is a fully functional task scheduling system that can be applied from small applications to large enterprise systems. The full function is reflected in the diversity of triggers, that is, simple timers and Cron expressions are supported; repetitive job tasks can be performed and exceptional calendars can be specified; tasks can also be diverse, as long as the IJob interface is inherited.
For small applications, Quartz.Net can be integrated into your system. For enterprise systems, it provides Routing support and Group to organize and manage tasks. In addition, there are persistence, plug-in functions, load balancing and fault migration to meet the needs of different application scenarios.
Hello Quartz.Net
Start using a framework, just like learning a development language, it's best to start with a Hello World program.
First create a sample program, and then add a reference to Quartz.Net.
Install-Package Quartz-Version 3.0.7
We are using the latest version 3.0.7 to demonstrate. After adding the reference, create a Job class, HelloQuartzJob.
Public class HelloQuartzJob: IJob {public Task Execute (IJobExecutionContext context) {return Task.Factory.StartNew (() = > {Console.WriteLine ("Hello Quartz.Net");});}}
This is a very simple Job class that outputs the text Hello Quartz.Net at execution time.
Next, we create a scheduler (Scheduler) when the program starts, and add a schedule for HelloQuartzJob:
Static async Task MainAsync () {var schedulerFactory = new StdSchedulerFactory (); var scheduler = await schedulerFactory.GetScheduler (); await scheduler.Start (); Console.WriteLine ($"Task Scheduler started"); / / create job and trigger var jobDetail = JobBuilder.Create () .Build () Var trigger = TriggerBuilder.Create () .WithSimpleSchedule (m = > {m.WithRepeatCount (3) .WithIntervalInSeconds (1);}) .build (); / / add scheduling await scheduler.ScheduleJob (jobDetail, trigger);}
Then run the program, and you will see the following figure:
As you can see from the demonstration, it usually takes four steps to perform a scheduled task:
Create a task scheduler. A scheduler is usually created when an application starts, and an application instance usually requires only one scheduler.
Create Job and JobDetail. Job is the type of job, which describes how the job is executed, and this class is defined by us; JobDetail is the encapsulation of the job by Quartz, which contains the Job type and the data used by Job during execution, as well as options such as whether to persist and whether to overwrite existing jobs.
Create a trigger. The trigger describes when the job is executed.
Add a schedule. When the above three steps are completed, the job can be scheduled.
Jobs: Job and JobDetail
Job is the type of job that describes how the job is executed, which is defined by us, such as HelloQuartzJob above. Job implements the IJob interface, while the IJob interface has only one Execute method, and the parameter context contains Scheduler, JobDetail, Trigger, and so on associated with the current context.
A typical Job definition is as follows:
Public class HelloQuartzJob: IJob {public Task Execute (IJobExecutionContext context) {return Task.Factory.StartNew (() = > {Console.WriteLine ("Hello Quartz.Net");});}} JobData
Job does not exist in isolation, it needs to execute parameters, how can these parameters be passed in? Let's define a Job class for demonstration.
Public class SayHelloJob: IJob {public string UserName {get; set;} public Task Execute (IJobExecutionContext context) {return Task.Factory.StartNew (() = > {Console.WriteLine ($"Hello {UserName}!");});}}
SayHelloJob requires the parameter UserName when it is executed, which is called JobData,Quartz.Net and is passed through JobDataMap. The code is as follows:
/ / create job var jobDetail = JobBuilder.Create () .SetJobData (new JobDataMap () {new KeyValuePair ("UserName", "Tom")}) .build ()
Through the SetJobData method of JobBuilder, pass in the JobDataMap object, which can contain multiple parameters, which can be mapped to the properties of the Job class. If we refine the code running example, we can see the following figure:
JobDetail
JobDetail is the encapsulation of a job by Quartz, which contains the Job type and the data used by Job during execution, as well as options such as whether to isolate storage, request a recovery job, and so on.
JobDetail is created through JobBuilder. For example:
Var jobDetail = JobBuilder.Create () .SetJobData (new JobDataMap () {new KeyValuePair ("UserName") "Tom")}) .StoreDurries (true) .RequestRecovery (true) .WithIdentity ("SayHelloJob-Tom", "DemoGroup") .WithDescription ("Say hello to Tom job") .build ()
Parameter description:
SetJobData: setting JobData
StoreDurably: orphaned storage, which means that the JobDetail will be stored even if it does not have an associated Trigger
RequestRecovery: request for recovery, which means that if the application crashes and starts again, the job will be executed again.
WithIdentity: unique identification of the job
WithDescription: job description information
In addition, Quartz.Net supports two very useful features:
DisallowConcurrentExecution: forbids parallel execution, which is effective for JobDetail
PersistJobDataAfterExecution: persists the JobData after execution is completed. This feature takes effect for the Job type, which means that all JobDetail using the Job will persist the JobData after the execution is complete.
Persistent JobData
Let's demonstrate this PersistJobDataAfterExecution feature. In SayHelloJob, we add a new field, RunSuccess, to record whether the task was executed successfully.
First add features to SayHelloJob:
[PersistJobDataAfterExecution] public class SayHelloJob: IJob {}
Then add JobData when you create the JobDetail:
Var jobDetail = JobBuilder.Create () .SetJobData (new JobDataMap () {new KeyValuePair ("UserName", "Tom"), new KeyValuePair ("RunSuccess", false)})
When Job is executed, update the value of RunSuccess:
Public Task Execute (IJobExecutionContext context) {return Task.Factory.StartNew (() = > {Console.WriteLine ($"Prev RunSuccess: {RunSuccess}"); Console.WriteLine ($"Hello {UserName}!"); context.JobDetail.JobDataMap.Put ("RunSuccess", true);});}
Next, let's take a look at the implementation effect:
Trigger: Trigger
Trigger is a trigger that is used to customize execution jobs. There are two types of Trigger: SampleTrigger and CronTrigger, which we will explain separately.
SampleTrigger
As the name implies, this is a simple trigger with the following features:
Repeat: WithRepeatCount () / RepeatForever ()
Set interval: WithInterval ()
Timing execution: StartAt () / StartNow ()
Set priority: WithPriority (), default is 5
It is important to note that when the Trigger reaches the time specified by the StartAt, it is executed once, and this time the execution is not included in the WithRepeatCount. As we can see in the example above, once the schedule is added, it is executed immediately, then repeated three times, and finally four times.
CronTrigger
CronTrigger completes the scheduling through Cron expressions. Cron expressions are very flexible and can meet the needs of almost all kinds of timing scenarios.
For Cron expressions, you can move to Quartz Cron expressions.
Examples of using CronTrigger are as follows:
Var trigger = TriggerBuilder.Create () .WithCronSchedule ("* / 1 *?") .build (); Calendar: Calendar
The Calendar can be associated with the Trigger to discharge the execution plan from the Trigger. For example, if you only want to execute your homework on a weekday, we can define a calendar for rest days, associate it with Trigger, and arrange the execution plan for rest days.
The sample code for Calendar is as follows:
Var calandar = new HolidayCalendar (); calandar.AddExcludedDate (DateTime.Today); await scheduler.AddCalendar ("holidayCalendar", calandar, false, false); var trigger = TriggerBuilder.Create () .WithCronSchedule ("* / 1 *?") .ModifiedByCalendar ("holidayCalendar") .build ()
In this example, we create a HolidayCalendar calendar and then add a date to exclude execution. After we add today to the exclusion date, the Trigger will not be triggered today.
Listener
JobListeners
TriggerListeners
SchedulerListeners
Listeners are another excellent feature of Quartz.Net, which allows us to write listeners to obtain job status and process job data at run time.
JobListener
JobListener can listen for pre-execution, post-execution, and reject events of Job execution. We demonstrate through the code:
Public class MyJobListener: IJobListener {public string Name {get;} = nameof (MyJobListener); public Task JobToBeExecuted (IJobExecutionContext context, CancellationToken cancellationToken = default) {/ / Job is about to execute return Task.Factory.StartNew (() = > {Console.WriteLine ($"Job: {context.JobDetail.Key} is about to be executed");}) } public Task JobExecutionVetoed (IJobExecutionContext context, CancellationToken cancellationToken = default) {return Task.Factory.StartNew (() = > {Console.WriteLine ($"Job: {context.JobDetail.Key} denied execution");}) } public Task JobWasExecuted (IJobExecutionContext context, JobExecutionException jobException, CancellationToken cancellationToken = default) {/ / Job execution completed return Task.Factory.StartNew (() = > {Console.WriteLine ($"Job: {context.JobDetail.Key} execution complete");}}
When the definition is complete, add the MyJobListener to the Scheduler:
Scheduler.ListenerManager.AddJobListener (new MyJobListener (), GroupMatcher.AnyGroup ())
Then we run the program, and we can see that Listener is called:
As you can see from the picture, both JobToBeExecuted and JobWasExecuted are executed, but JobExecutionVetoed is not executed, so how to trigger JobExecutionVetoed? Please continue to read the TriggerListener demo.
TriggerListener
TriggerListener can monitor the execution of Trigger, which we demonstrate through code:
Public class MyTriggerListener: ITriggerListener {public string Name {get;} = nameof (MyTriggerListener); public Task TriggerComplete (ITrigger trigger, IJobExecutionContext context, SchedulerInstruction triggerInstructionCode, CancellationToken cancellationToken = default) {return Task.CompletedTask;} public Task TriggerFired (ITrigger trigger, IJobExecutionContext context, CancellationToken cancellationToken = default) {return Task.CompletedTask;} public Task TriggerMisfired (ITrigger trigger, CancellationToken cancellationToken = default) {return Task.CompletedTask } public Task VetoJobExecution (ITrigger trigger, IJobExecutionContext context, CancellationToken cancellationToken = default) {return Task.FromResult (true); / / returns true to reject Job to continue execution}}
Add MyTriggerListener to the Scheduler:
Scheduler.ListenerManager.AddTriggerListener (new MyTriggerListener (), GroupMatcher.AnyGroup ())
You can see the following effect by running the code:
As you can see from the picture, the JobExecutionVetoed in JobListener is executed.
SchedulerListener
ISchedulerListener provides listening for Job and Trigger management. Events related to the scheduler include: adding jobs / triggers, deleting jobs / triggers, serious errors in the scheduler, notification of scheduler shutdown, and so on. The complete interface definition is as follows:
Public interface ISchedulerListener {Task JobAdded (IJobDetail jobDetail, CancellationToken cancellationToken = default); Task JobDeleted (JobKey jobKey, CancellationToken cancellationToken = default); Task JobInterrupted (JobKey jobKey, CancellationToken cancellationToken = default); Task JobPaused (JobKey jobKey, CancellationToken cancellationToken = default); Task JobResumed (JobKey jobKey, CancellationToken cancellationToken = default); Task JobScheduled (ITrigger trigger, CancellationToken cancellationToken = default); Task JobsPaused (string jobGroup, CancellationToken cancellationToken = default); Task JobsResumed (string jobGroup, CancellationToken cancellationToken = default); Task JobUnscheduled (TriggerKey triggerKey, CancellationToken cancellationToken = CancellationToken cancellationToken) Task SchedulerError (string msg, SchedulerException cause, CancellationToken cancellationToken = default); Task SchedulerInStandbyMode (CancellationToken cancellationToken = default); Task SchedulerShutdown (CancellationToken cancellationToken = default); Task SchedulerShuttingdown (CancellationToken cancellationToken = default); Task SchedulerStarted (CancellationToken cancellationToken = default); Task SchedulerStarting (CancellationToken cancellationToken = default); Task SchedulingDataCleared (CancellationToken cancellationToken = default); Task TriggerFinalized (ITrigger trigger, CancellationToken cancellationToken = default); Task TriggerPaused (TriggerKey triggerKey, CancellationToken cancellationToken = default); Task TriggerResumed (TriggerKey triggerKey, CancellationToken cancellationToken = default) Task TriggersPaused (string triggerGroup, CancellationToken cancellationToken = default); Task TriggersResumed (string triggerGroup, CancellationToken cancellationToken = default);}
The code to add SchedulerListener is as follows:
Scheduler.ListenerManager.AddSchedulerListener (mySchedListener); persistence: JobStore
Quartz.Net supports the persistence operation of Job, which is called JobStore. By default, Quartz persists data into memory, the advantage is that the memory is fast, the disadvantage is that it cannot provide load balancing support, and after the program crashes, we will lose all Job data, for enterprise systems, the disadvantages obviously outweigh the benefits, so it is necessary to store the data in the database.
ADO.NET storage
Quartz uses ADO.NET to access databases and supports a wide range of database vendors:
SqlServer-SQL Server driver for .NET Framework 2.0
Oracle driver for OracleODP-Oracle
Oracle 11 managed driver for OracleODPManaged-Oracle
MySql-MySQL Connector / .NET
SQLite-SQLite ADO.NET Provider
SQLite-Microsoft-Microsoft SQLite ADO.NET Provider
Firebird-Firebird ADO.NET provider
Npgsql-PostgreSQL Npgsql
The database creation statement can be found in the source code of Quartz.Net: https://github.com/quartznet/quartznet/tree/master/database/tables
We can configure Quartz to use database storage through a configuration file:
# job storequartz.jobStore.type = Quartz.Impl.AdoJobStore.JobStoreTX, Quartzquartz.jobStore.dataSource = quartz_storequartz.jobStore.driverDelegateType = Quartz.Impl.AdoJobStore.PostgreSQLDelegate, Quartz#quartz.jobStore.useProperties = truequartz.dataSource.quartz_store.connectionString = Server=localhost;Database=quartz_store;userid=quartz_net;password=xxxxxx;Pooling=true;MinPoolSize=1;MaxPoolSize=10;Timeout=15;SslMode=Disable;quartz.dataSource.quartz_store.provider = Npgsql load balancer
Load balancing is a way to achieve high availability, when the task becomes larger, a single server is difficult to meet the needs, the use of load balancing makes the system has the ability to scale out, through the deployment of multiple nodes to increase the ability to deal with Job.
Quartz.Net relies on ADO JobStore when using load balancing, which means you need to use a database to persist data. Then we can use the following configuration to complete the load balancing function:
Quartz.jobStore.clustered = truequartz.scheduler.instanceId = AUTO
Clustered: identification of the cluster
InstanceId: the ID of the current Scheduler instance. The ID of each example cannot be repeated. When using AUTO, the system will automatically generate ID.
When we run an Scheduler instance on multiple servers, we need to set the server clock time to ensure that the server time is the same. For the windows server, you can set the automatic synchronization time from the network.
Access Quartz instances through Routing
The function of accessing Quartz instances through Routing provides a good way for us to do system separation.
We can achieve server-side remote access to Quartz through the following configuration:
# export this server to remoting contextquartz.scheduler.exporter.type = Quartz.Simpl.RemotingSchedulerExporter, Quartzquartz.scheduler.exporter.port = 555quartz.scheduler.exporter.bindName = QuartzSchedulerquartz.scheduler.exporter.channelType = tcpquartz.scheduler.exporter.channelName = httpQuartz
Then we configure access on the client system:
Quartz.scheduler.proxy = truequartz.scheduler.proxy.address = tcp://localhost:555/QuartzScheduler development practice
The ideal task scheduling system should be a background service, which runs silently in the background of the system, and the business system completes the operations of adding and deleting tasks through the interface. When building Windows services, you can integrate with TopShelf to complete the development of windows services.
Install-Package Topshelf
Another problem with service development is that Quartz itself does not support dependency injection, but to solve the problem of dependency injection, you can use Autofac. Fortunately, there are great gods who have completed the integration of TopShelf and Autofac, so we just need to use it.
Install-Package Topshelf.Autofac
There are two ways to add Quartz.Net Job: dynamically at run time and through configuration files. It is recommended to add dynamically (the sample code is added dynamically), unless your Job is relatively fixed.
The configuration of Scheduler can be done in the form of configuration files to facilitate maintenance during deployment.
At this point, I believe you have a deeper understanding of "what is the use of Quartz.Net?" you might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.