Use mongodb as the JobStore in Quartz. Net to implement the underlying persistence mechanism. mongodbquartz.net
We all know that the underlying layer of Quartz uses RAMJobStore by default. All jobs, triggers, and Calendar are stored using data structures such as Dictionary and SortSet.
I'm sure I can't say it quickly, but I still cannot take advantage of it in the face of the disaster and restart, and it's all in the memory, and I cannot build a Quartz cluster with multiple machines. This is annoying, although
Some relational persistent storage solutions are provided, but it is a pity that the official support is not supported in the face of today's popular nosql. However, the plug-in Design Based on Quartz itself is not a problem.
I. IJobStore
Download the source code from github: Ghost.
Then you can see several sub-classes of RAMJobStore with full memory.
public class RAMJobStore: IJobStore{....}
And JobStoreTX with and without locks under JobStoreSupport.
Public class JobStoreSupport: IJobStore {....} // lock mechanism public class JobStoreTX: JobStoreSupport {....} // public class JobStoreCMT: JobStoreSupport {....}
So you should understand that the Redis and Mongodb JobStore storage mentioned in this lesson must also implement the IJobStore interface, right.
Ii. MongoDB JobStore
1. Install mongodb
Since you want to use mongodb, you must have mongodb installation program, you can go to the official website: wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.4.5.tgz,
Here I use centos on the linux platform.
2. pull dll on nuget
You can run Install-Package Quartz. Spi. MongoDbJobStore on the nuget console, as shown below:
PM> Install-Package Quartz. spi. mongoDbJobStore is trying to collect data and the target is ". Z. spi. the dependency information of MongoDbJobStore.2.0.0 is trying to parse the package "Quartz. spi. dependency of MongoDbJobStore.2.0.0. DependencyBehavior is "Lowest" and is being parsed to install the Quartz package. spi. mongoDbJobStore.2.0.0 "parsed operation to install the package" Quartz. spi. mongoDbJobStore.2.0.0 "is converting the package" Common. logging. core.3.3.1 "added to the folder" C: \ 1 \ ConsoleApplication1 \ packages "The package" Common. logging. core.3.3.1 "added to the folder" C: \ 1 \ ConsoleApplication1 \ packages "The package" Common. logging. add Core.3.3.1 to packages. config "has added" Common. logging. core 3.3.1 "is successfully installed to leleapplication1 and the package" Common. logging.3.3.1 "added to the folder" C: \ 1 \ ConsoleApplication1 \ packages "The package" Common. logging.3.3.1 "added to the folder" C: \ 1 \ ConsoleApplication1 \ packages "The package" Common. add Logging.3.3.1 to packages. config "has added" Common. logging 3.3.1 "successfully installed to leleapplication1. The package" MongoDB. bson.2.4.2 "added to the folder" C: \ 1 \ ConsoleApplication1 \ packages "The package" MongoDB. bson.2.4.2 "added to the folder" C: \ 1 \ ConsoleApplication1 \ packages "The package" MongoDB. bson.2.4.2 "added to" packages. config "has changed" MongoDB. bson 2.4.2 "is successfully installed on ConsoleApplication1. Adding the Quartz.2.4.1 package to the folder" C: \ 1 \ ConsoleApplication1 \ packages "has added the package" Quartz.2.4.1 "to the folder" C: \ 1 \ leleapplication1 \ packages "added the Quartz.2.4.1 package to packages. config "has successfully installed Quartz 2.4.1 to leleapplication1. The package" System. runtime. interopServices. runtimeInformation.4.3.0 "added to the folder" C: \ 1 \ ConsoleApplication1 \ packages "The package" System. runtime. interopServices. runtimeInformation.4.3.0 "added to the folder" C: \ 1 \ ConsoleApplication1 \ packages "The package" System. runtime. interopServices. runtimeInformation.4.3.0 "to" packages. config. runtime. interopServices. runtimeInformation 4.3.0 "is successfully installed to leleapplication1 and the package" MongoDB. driver. core.2.4.2 "added to the folder" C: \ 1 \ ConsoleApplication1 \ packages "The package" MongoDB. driver. core.2.4.2 "added to the folder" C: \ 1 \ ConsoleApplication1 \ packages "The package" MongoDB. driver. add Core.2.4.2 to packages. config "has changed" MongoDB. driver. core 2.4.2 "is successfully installed to leleapplication1 and the package" MongoDB. driver.2.4.2 "added to the folder" C: \ 1 \ ConsoleApplication1 \ packages "The package" MongoDB. driver.2.4.2 "added to the folder" C: \ 1 \ ConsoleApplication1 \ packages "The package" MongoDB. add Driver.2.4.2 to packages. config "has changed" MongoDB. driver 2.4.2 "is successfully installed to ConsoleApplication1 and the package" Quartz. spi. mongoDbJobStore.2.0.0 "is added to the" C: \ 1 \ ConsoleApplication1 \ packages "folder. The package" Quartz. spi. mongoDbJobStore.2.0.0 "is added to the" C: \ 1 \ ConsoleApplication1 \ packages "folder. The package" Quartz. spi. mongoDbJobStore.2.0.0 "to" packages. in config, "Quartz. spi. mongoDbJobStore 2.0.0 "is successfully installed on leleapplication1
You can also download the source code: https://github.com/chrisdrobison/mongodb-quartz-net in github
3. Start running
Next, let's take a look at the default configuration on Basic Usage # on this page:
1 var properties = new NameValueCollection(); 2 properties[StdSchedulerFactory.PropertySchedulerInstanceName] = instanceName; 3 properties[StdSchedulerFactory.PropertySchedulerInstanceId] = $"{Environment.MachineName}-{Guid.NewGuid()}"; 4 properties[StdSchedulerFactory.PropertyJobStoreType] = typeof (MongoDbJobStore).AssemblyQualifiedName; 5 // I treat the database in the connection string as the one you want to connect to 6 properties[$"{StdSchedulerFactory.PropertyJobStorePrefix}.{StdSchedulerFactory.PropertyDataSourceConnectionString}"] = "mongodb://localhost/quartz"; 7 // The prefix is optional 8 properties[$"{StdSchedulerFactory.PropertyJobStorePrefix}.collectionPrefix"] = "prefix"; 9 10 var scheduler = new StdSchedulerFactory(properties);11 return scheduler.GetScheduler();
<1> PropertySchedulerInstanceName: This is the configuration of the Name of Scheduler. You can define a concise Name as needed.
<2> PropertySchedulerInstanceId: The machineName + NewGuid is used to ensure the unique SchedulerID of the Scheduler container.
It is used in Cluster to ensure uniqueness, but the above Code is a bit cumbersome, in fact, as long as you write "AUTO", from the underlying
SimpleInstanceIdGenerator ensures uniqueID generation, as shown in the source code of StdSchedulerFactory. Instantiate:
1 if (schedInstId.Equals(AutoGenerateInstanceId)) 2 { 3 autoId = true; 4 instanceIdGeneratorType = LoadType(cfg.GetStringProperty(PropertySchedulerInstanceIdGeneratorType)) ?? typeof(SimpleInstanceIdGenerator); 5 } 6 else if (schedInstId.Equals(SystemPropertyAsInstanceId)) 7 { 8 autoId = true; 9 instanceIdGeneratorType = typeof(SystemPropertyInstanceIdGenerator);10 }
<3> PropertyJobStoreType: This attribute uses MongoDbJobStore as the underlying IJobStore implementer.
<4> PropertyDataSourceConnectionString, collectionPrefix: There is nothing to say about these two. One is the connectionstring of mongodb, and the other is the prefix of collection.
Okay, the following is my complete code:
1 static void Main(string[] args) 2 { 3 4 LogManager.Adapter = new Common.Logging.Simple.TraceLoggerFactoryAdapter() 5 { 6 Level = LogLevel.All 7 }; 8 9 var properties = new NameValueCollection();10 properties[StdSchedulerFactory.PropertySchedulerInstanceId] = "AUTO";11 properties[StdSchedulerFactory.PropertyJobStoreType] = typeof(MongoDbJobStore).AssemblyQualifiedName;12 13 // I treat the database in the connection string as the one you want to connect to14 properties[$"{StdSchedulerFactory.PropertyJobStorePrefix}.{StdSchedulerFactory.PropertyDataSourceConnectionString}"] = "mongodb://192.168.23.163/quartz";15 16 // The prefix is optional17 properties[$"{StdSchedulerFactory.PropertyJobStorePrefix}.collectionPrefix"] = "prefix";18 19 var factory = new StdSchedulerFactory(properties);20 21 //scheduler22 IScheduler scheduler = factory.GetScheduler();23 24 scheduler.Start();25 26 var job = JobBuilder.Create<HelloJob>().WithIdentity("test", "datamip").Build();27 28 var trigger = TriggerBuilder.Create().WithCronSchedule("* * * * * ?").Build();29 30 if (!scheduler.CheckExists(job.Key))31 {32 scheduler.ScheduleJob(job, trigger);33 }34 35 Console.Read();36 }
In my custom HelloJob, I specifically recorded the schedulscheduling time schedulertime and nextFireTime that the Trigger should Trigger.
1 class HelloJob : IJob 2 { 3 static int index = 1; 4 5 public void Execute(IJobExecutionContext context) 6 { 7 Console.WriteLine("{4} index={0},current={1}, scheuler={2},nexttime={3}", 8 index++, DateTime.Now, 9 context.ScheduledFireTimeUtc?.LocalDateTime,10 context.NextFireTimeUtc?.LocalDateTime,11 context.JobDetail.JobDataMap["key"]);12 }13 }
Run the following command:
Go to the database through robomongo and check that there are five collection items with data in them.
Well, this article will talk about it. Of course, there is also redis-based JobStore. If you are interested, please try it yourself.