第9课小结:
JobStore的职责是持续跟踪您给调度程序的所有“工作数据”:作业、触发器、日历等等。
一、RAMJobStore
RAMJobStore是最简单的JobStore ,它也是最高效的(在CPU时间方面)。它将所有的数据保存在RAM中。
优点:闪电般的速度。
缺点:当应用程序结束(或崩溃)时,所有的调度信息都会丢失。
二、JDBCJobStore
JDBCJobStore通过JDBC将所有数据保存在数据库中。
优点:当应用程序结束(或崩溃)时,所有的调度信息不会丢失。
缺点:配置比RAMJobStore更复杂,而且也没有那么快。但现代的服务器中,如果有主键上构建带有索引的数据库表,而且调度器与数据库之间连接是使用良好的局域网通读,性能与RAMStore相比差距不太大。
JDBCJobStore几乎与任何数据库一起工作,需要指定以下几个参数:
1.Quartz表的表前缀,可以手动指定配置。(docs/dbTables”目录中创建Quartz表都默认QRTZ_开头)
示例:org.quartz.jobStore.tablePrefix = QRTZ_
2.指定需要什么类型的事务
a.JobStoreTX:如果您不需要将调度命令(例如添加和删除触发器)绑定到其他事务,那么您可以让Quartz使用JobStoreTX为您的JobStore(这是最常见的选择)来管理事务。
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
b.JobStoreCMT:如果您需要Quartz来处理其他事务(例如在J2EE应用程序服务器中),那么您应该使用JobStoreCMT——在这种情况下,Quartz将允许应用服务器容器管理事务。
3.建立数据源
a.通过提供数据库的所有连接信息,让Quartz创建并管理数据源本身。
b.让Quartz使用应用程序服务器管理的数据源,通过提供JDBCJobStore的JNDI名称。
org.quartz.jobStore.dataSource = myDS
4.JobStore的驱动程序代理
a.StdJDBCDelegate是一个使用“香草”JDBC代码(和SQL语句)来完成其工作的代理。如果没有专门为数据库指定的代理,请尝试使用这个代理。
b.使用对应数据库的代理,这是最好的方式。如:HSQLDBDelegate(用于HSQLDB)、MSSQLDelegate(用于Microsoft SQLServer)
示例:org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
5.数据源中的连接数量
如果您的调度器很忙(也就是说,几乎总是执行与线程池大小相同的作业数量,那么您应该将数据源中的连接数量设置为线程池+2的大小。
org.quartz.threadPool.threadCount = 3
org.quartz.dataSource.myDS.maxConnections = 5 (等于线程池 3 + 2 = 5 )
6.让JDBCJobStore,JobDataMaps中的所有值都是字符串
使JDBCJobStore,JobDataMaps中的所有值都是字符串,因此可以作为名称-值对存储,而不是在BLOB列中存储更复杂的对象。从长远来看,这要安全得多,因为您避免了将非string类序列化成BLOB的类版本控制问题。
org.quartz.jobStore.useProperties=true(默认是false)
三、TerracottaJobStore
TerracottaJobStore在不使用数据库的情况下提供了扩展和健壮性的方法。这意味着您的数据库可以不受Quartz的负载影响。
数据存储在Terracotta服务器中。它的性能比通过JDBCJobStore使用数据库要好得多(大约是一个数量级),但比RAMJobStore要慢得多。
1.指定JobStore
org.quartz.jobStore.class = org.terracotta.quartz.TerracottaJobStore
2.指定Terracotta服务器的位置
org.quartz.jobStore.tcConfigUrl = localhost:9510
示例1:RAMJobStore
org.quartz.scheduler.instanceName = MyScheduler
org.quartz.threadPool.threadCount = 5
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
示例2:JDBCJobStore
org.quartz.scheduler.instanceName = MyScheduler
org.quartz.threadPool.threadCount = 3
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.dataSource = myDS
org.quartz.dataSource.myDS.driver = com.mysql.jdbc.Driver
org.quartz.dataSource.myDS.URL = jdbc:mysql://localhost:3306/ll?characterEncoding=utf-8
org.quartz.dataSource.myDS.user = root
org.quartz.dataSource.myDS.password = 123456
org.quartz.dataSource.myDS.maxConnections = 5
Lesson 9: Job Stores
JobStore’s are responsible for keeping track of all the “work data” that you give to the scheduler: jobs, triggers, calendars, etc. Selecting the appropriate JobStore for your Quartz scheduler instance is an important step. Luckily, the choice should be a very easy one once you understand the differences between them. You declare which JobStore your scheduler should use (and it’s configuration settings) in the properties file (or object) that you provide to the SchedulerFactory that you use to produce your scheduler instance.
Never use a JobStore instance directly in your code. For some reason many people attempt to do this. The JobStore is for behind-the-scenes use of Quartz itself. You have to tell Quartz (through configuration) which JobStore to use, but then you should only work with the Scheduler interface in your code.
JobStore的职责是持续跟踪您给调度程序的所有“工作数据”:作业、触发器、日历等等。为您的Quartz调度程序选择适当的JobStore是一个重要的步骤。幸运的是,一旦你理解了它们之间的区别,选择应该是非常简单的。
你可以在属性文件quartz.properties(或对象中,直接实例化JobStore类)声明你的scheduler将会使用哪种JobStore。这个JobStore对象会提供给用来产生scheduler实例的SchedulerFactory类。
不要直接在代码中使用JobStore实例。出于某种原因,许多人试图这样做。JobStore是用于后台Quartz自己使用的。您必须告诉Quartz(通过配置)要使用哪一种JobStore,而在你在代码中,你应该只使用Scheduler 接口(不需要再为schduler实例化指定一个JobStore,因为已在quartz.properties中配置了)。
RAMJobStore
RAMJobStore is the simplest JobStore to use, it is also the most performant (in terms of CPU time). RAMJobStore gets its name in the obvious way: it keeps all of its data in RAM. This is why it’s lightning-fast, and also why it’s so simple to configure. The drawback is that when your application ends (or crashes) all of the scheduling information is lost - this means RAMJobStore cannot honor the setting of “non-volatility” on jobs and triggers. For some applications this is acceptable - or even the desired behavior, but for other applications, this may be disastrous.
RAMJobStore
RAMJobStore是最简单的JobStore ,它也是最高效的(在CPU时间方面)。RAMJobStore以显而易见的方式获得了它的名字:它将所有的数据保存在RAM中。这就是为什么它是闪电般的速度,也是为什么它如此简单的配置。缺点是当应用程序结束(或崩溃)时,所有的调度信息都会丢失——这意味着RAMJobStore无法在Job和Trigger上设置“非易失性”的设置。对于某些应用程序,这是可以接受的,甚至是它们所希望的行为特性,但是对于其他应用程序来说,这可能是灾难性的。
To use RAMJobStore (and assuming you’re using StdSchedulerFactory) simply specify the class name org.quartz.simpl.RAMJobStore as the JobStore class property that you use to configure quartz:
要使用RAMJobStore(假设您正在使用StdSchedulerFactory),只需指定类名org.quartz.simpl.RAMJobStore作为您用来配置quartz的JobStore类属性,而不需要你需要担当的其它设置了,示例如下:
Configuring Quartz to use RAMJobStore
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
There are no other settings you need to worry about.
JDBCJobStore
JDBCJobStore is also aptly named - it keeps all of its data in a database via JDBC. Because of this it is a bit more complicated to configure than RAMJobStore, and it also is not as fast. However, the performance draw-back is not terribly bad, especially if you build the database tables with indexes on the primary keys. On fairly modern set of machines with a decent LAN (between the scheduler and database) the time to retrieve and update a firing trigger will typically be less than 10 milliseconds.
JDBCJobStore也被恰如其分地命名为——它通过JDBC将所有数据保存在数据库中。正因为如此,配置比RAMJobStore更复杂,而且也没有那么快。但是性能缺点也并不是这么糟糕,特别是如果您在主键上构建带有索引的数据库表的话。因为在现代的机器上,调度器和数据库之间的连接使用良好的局域网通讯,检索和更新一个触发的触发器的时间通常小于10毫秒。
所以相比RAMStore基本上也没有什么性能上的影响。
JDBCJobStore works with nearly any database, it has been used widely with Oracle, PostgreSQL, MySQL, MS SQLServer, HSQLDB, and DB2. To use JDBCJobStore, you must first create a set of database tables for Quartz to use. You can find table-creation SQL scripts in the “docs/dbTables” directory of the Quartz distribution. If there is not already a script for your database type, just look at one of the existing ones, and modify it in any way necessary for your DB. One thing to note is that in these scripts, all the the tables start with the prefix “QRTZ_” (such as the tables “QRTZ_TRIGGERS”, and “QRTZ_JOB_DETAIL”). This prefix can actually be anything you’d like, as long as you inform JDBCJobStore what the prefix is (in your Quartz properties). Using different prefixes may be useful for creating multiple sets of tables, for multiple scheduler instances, within the same database.
JDBCJobStore几乎与任何数据库一起工作,它已经广泛地应用于Oracle、PostgreSQL、MySQL、MS SQLServer、HSQLDB和DB2。要使用JDBCJobStore,您必须首先创建一组用于Quartz的数据库表。您可以在Quartz发行版的“docs/dbTables”目录中找到表格创建的SQL脚本。如果您的数据库类型还没有一个脚本,只需查看现存的一个脚本,并以任何必要的方式对数据库进行修改。需要注意的一点是,在这些脚本中,所有的表都以前缀“QRTZ”开头(如表“QRTZ_TRIGGERS”和“QRTZ_JOB_DETAIL”)。这个前缀实际上你是可以随意调整的,只要您在quartz.properies文件中指定JDBCJobStore前缀是什么即可。使用不同的前缀对于在同一个数据库中为多个调度器实例创建多个表可能非常有用。
Once you’ve got the tables created, you have one more major decision to make before configuring and firing up JDBCJobStore. You need to decide what type of transactions your application needs. If you don’t need to tie your scheduling commands (such as adding and removing triggers) to other transactions, then you can let Quartz manage the transaction by using JobStoreTX as your JobStore (this is the most common selection).
一旦您已经创建了表格,在配置和启动JDBCJobStore之前,您还有一个重要的决定要做。您需要决定应用程序需要什么类型的事务。如果您不需要将调度命令(例如添加和删除触发器)绑定到其他事务,那么您可以让Quartz使用JobStoreTX为您的JobStore(这是最常见的选择)来管理事务。
If you need Quartz to work along with other transactions (i.e. within a J2EE application server), then you should use JobStoreCMT - in which case Quartz will let the app server container manage the transactions.
The last piece of the puzzle is setting up a DataSource from which JDBCJobStore can get connections to your database. DataSources are defined in your Quartz properties using one of a few different approaches. One approach is to have Quartz create and manage the DataSource itself - by providing all of the connection information for the database. Another approach is to have Quartz use a DataSource that is managed by an application server that Quartz is running inside of - by providing JDBCJobStore the JNDI name of the DataSource. For details on the properties, consult the example config files in the “docs/config” folder.
To use JDBCJobStore (and assuming you’re using StdSchedulerFactory) you first need to set the JobStore class property of your Quartz configuration to be either org.quartz.impl.jdbcjobstore.JobStoreTX or org.quartz.impl.jdbcjobstore.JobStoreCMT - depending on the selection you made based on the explanations in the above few paragraphs.
Configuring Quartz to use JobStoreTx
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
如果您需要Quartz来处理其他事务(例如在J2EE应用程序服务器中),那么您应该使用JobStoreCMT——在这种情况下,Quartz将允许应用服务器容器管理事务。
最后一个难题是建立一个数据源,使JDBCJobStore可以连接到数据库。数据源是在quartz.properies中定义的,有几种不同的方法来定义。
1、通过提供数据库的所有连接信息,让Quartz创建并管理数据源本身。
2、让Quartz使用应用程序服务器管理的数据源(如在项目中spring配置的数据源),通过提供JDBCJobStore的JNDI名称。有关属性的详细信息,请参考“docs/config”文件夹中的示例配置文件。
要使用JDBCJobStore(假设您正在使用StdSchedulerFactory),您首先需要将Quartz配置的JobStore类属性设置为org.quartz.impl.jdbcjobstore.JobStoreTX或org.quartz.impl.jdbcjobstore.JobStoreCMT-----你可以根据上面对于这两种类型说明来选择其中一种。
Next, you need to select a DriverDelegate for the JobStore to use. The DriverDelegate is responsible for doing any JDBC work that may be needed for your specific database. StdJDBCDelegate is a delegate that uses “vanilla” JDBC code (and SQL statements) to do its work. If there isn’t another delegate made specifically for your database, try using this delegate - we’ve only made database-specific delegates for databases that we’ve found problems using StdJDBCDelegate with (which seems to be most!). Other delegates can be found in the “org.quartz.impl.jdbcjobstore” package, or in its sub-packages. Other delegates include DB2v6Delegate (for DB2 version 6 and earlier), HSQLDBDelegate (for HSQLDB), MSSQLDelegate (for Microsoft SQLServer), PostgreSQLDelegate (for PostgreSQL), WeblogicDelegate (for using JDBC drivers made by Weblogic), OracleDelegate (for using Oracle), and others.
Once you’ve selected your delegate, set its class name as the delegate for JDBCJobStore to use.
接下来,您需要选择要使用的JobStore的驱动程序代理。驱动代理负责执行您的特定数据库可能需要的任何JDBC工作。StdJDBCDelegate是一个使用“香草”JDBC代码(和SQL语句)来完成其工作的代理。如果没有专门为数据库指定的代理,请尝试使用这个代理——我们只有在发现使用StdJDBCDelegate存在问题时(这似乎是最重要的!),才为数据库指定了特定于数据库的代理。其他的代理可以在“org.quartz.impl.jdbcjobstore”包中找到,或者在它的子包中。其他的代理包括DB2v6Delegate(用于DB2 version 6和更早版本)、HSQLDBDelegate(用于HSQLDB)、MSSQLDelegate(用于Microsoft SQLServer)、PostgreSQLDelegate(用于PostgreSQL)、WeblogicDelegate(用于使用Weblogic所做的JDBC驱动程序)、OracleDelegate(用于使用Oracle)等等。
一旦你选择了你的代理,就把它的类名设置为JDBCJobStore的代理。
Configuring JDBCJobStore to use a DriverDelegate
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
Next, you need to inform the JobStore what table prefix (discussed above) you are using.
下一步,你需要指定JobStore使用什么样的表前缀,示例如下:
Configuring JDBCJobStore with the Table Prefix
org.quartz.jobStore.tablePrefix = QRTZ_
And finally, you need to set which DataSource should be used by the JobStore. The named DataSource must also be defined in your Quartz properties. In this case, we’re specifying that Quartz should use the DataSource name “myDS” (that is defined elsewhere in the configuration properties).
最后,您需要设置JobStore应该使用哪个数据源。指定的数据源也必须在Quartz属性中定义。在这种情况下,我们指定Quartz应该使用DataSource名称“myDS”(这是在配置属性的其他地方定义的)。
Configuring JDBCJobStore with the name of the DataSource to use
org.quartz.jobStore.dataSource = myDS
If your Scheduler is busy (i.e. nearly always executing the same number of jobs as the size of the thread pool, then you should probably set the number of connections in the DataSource to be the about the size of the thread pool + 2.
The "org.quartz.jobStore.useProperties" config parameter can be set to "true" (defaults to false) in order to instruct JDBCJobStore that all values in JobDataMaps will be Strings, and therefore can be stored as name-value pairs, rather than storing more complex objects in their serialized form in the BLOB column. This is much safer in the long term, as you avoid the class versioning issues that there are with serializing your non-String classes into a BLOB.
如果您的调度器很忙(也就是说,几乎总是执行与线程池大小相同的作业数量,那么您应该将数据源中的连接数量设置为线程池+2的大小。
“org.quartz.jobStore.useProperties“配置参数可以设置为”true“(默认为false),以便指示JDBCJobStore,JobDataMaps中的所有值都是字符串,因此可以作为名称-值对存储,而不是在BLOB列中存储更复杂的对象。从长远来看,这要安全得多,因为您避免了将非string类序列化成BLOB的类版本控制问题。
TerracottaJobStore
TerracottaJobStore provides a means for scaling and robustness without the use of a database. This means your database can be kept free of load from Quartz, and can instead have all of its resources saved for the rest of your application.
TerracottaJobStore can be ran clustered or non-clustered, and in either case provides a storage medium for your job data that is persistent between application restarts, because the data is stored in the Terracotta server. It’s performance is much better than using a database via JDBCJobStore (about an order of magnitude better), but fairly slower than RAMJobStore.
To use TerracottaJobStore (and assuming you’re using StdSchedulerFactory) simply specify the class name org.quartz.jobStore.class = org.terracotta.quartz.TerracottaJobStore as the JobStore class property that you use to configure quartz, and add one extra line of configuration to specify the location of the Terracotta server:
TerracottaJobStore在不使用数据库的情况下提供了扩展和健壮性的方法。这意味着您的数据库可以不受Quartz的负载影响,而是可以将所有的资源保存到您的应用程序的其余的地方。
TerracottaJobStore可以是集群的或非集群的,在这两种情况下,都为您的作业数据提供了存储介质,保证了在应用程序重启后,数据仍不会丢失。因为数据存储在Terracotta服务器中。它的性能比通过JDBCJobStore使用数据库要好得多(大约是一个数量级),但比RAMJobStore要慢得多。
使用TerracottaJobStore(假设您正在使用StdSchedulerFactory)只是简单地指定类名org.quartz.jobStore.class = org.terracotta.quartz.TerracottaJobStore来作为JobStore类的属性,及一个额外的配置行来指定Terracotta服务器的位置:
Configuring Quartz to use TerracottaJobStore
org.quartz.jobStore.class = org.terracotta.quartz.TerracottaJobStore
org.quartz.jobStore.tcConfigUrl = localhost:9510
More information about this JobStore and Terracotta can be found at http://www.terracotta.org/quartz
示例:三种JobStore不同的配置方式
1、RAMJobStore:很简单,就一个配置参数
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
2、JDBCJobStore:使用JobStoreTx
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#配置表的前缀
org.quartz.jobStore.tablePrefix = QRTZ_
#使用JNDI数据源的时候,数据源的名字
org.quartz.jobStore.dataSource = myDS
3、TerracottaJobStore:配置参数
org.quartz.jobStore.class = org.terracotta.quartz.TerracottaJobStore
org.quartz.jobStore.tcConfigUrl = localhost:9510
Pasted from <http://www.quartz-scheduler.org/documentation/quartz-2.2.x/tutorials/tutorial-lesson-09.html>