JobStore 负责跟踪您提供给调度程序的所有“工作数据”:作业、触发器、日历等。为您的 Quartz 调度程序实例选择适当的 IJobStore
实现是重要的一步。 幸运的是,一旦您了解了它们之间的差异,选择应该是一个非常简单的选择。 您在提供给用于生成调度程序实例的 SchedulerFactory 的属性文件(或对象)中声明调度程序应使用的 JobStore(及其配置设置)。
警告
切勿在代码中直接使用 JobStore 实例。 出于某种原因,许多人试图这样做。 JobStore 用于 Quartz 本身的幕后使用。 你必须告诉 Quartz(通过配置)使用哪个 JobStore,但是你应该只在代码中使用 Scheduler 接口。
RAMJobStore
RAMJobStore
是使用起来最简单的 JobStore,它也是性能最高的(就 CPU 时间而言)。 RAMJobStore
以显而易见的方式得名:它将所有数据保存在 RAM 中。 这就是它闪电般快速的原因,也是配置如此简单的原因。 缺点是当您的应用程序结束(或崩溃)时,所有调度信息都将丢失 - 这意味着 RAMJobStore 无法遵守作业和触发器的“非易失性”设置。 对于某些应用程序,这是可以接受的 —— 甚至是所需的行为,但对于其他应用程序,这可能是灾难性的。
配置 Quartz 以使用 RAMJobStore
// this is actually the default, so you don't need to explicitly set this
quartz.jobStore.type = Quartz.Simpl.RAMJobStore, Quartz
要使用 RAMJobStore
(假设您使用的是 StdSchedulerFactory
),您不需要做任何特别的事情。 Quartz.NET 的默认配置使用 RAMJobStore
作为作业存储实现。
ADO.NET 作业存储 (AdoJobStore)
AdoJobStore 的命名也很恰当 —— 它通过 ADO.NET 将所有数据保存在数据库中。正因为如此,它的配置比 RAMJobStore
稍微复杂一些,而且速度也没有那么快。但是,性能下降并不是非常糟糕,特别是如果您使用主键上的索引构建数据库表。
要使用 AdoJobStore,您必须首先创建一组数据库表供 Quartz.NET 使用。您可以在 Quartz.NET 发行版的“database/dbtables”目录中找到创建表的 SQL 脚本。如果您的数据库类型还没有脚本,只需查看现有脚本之一,并以您的数据库所需的任何方式对其进行修改。需要注意的一点是,在这些脚本中,所有表都以前缀 QRTZ_
开头(例如表 QRTZ_TRIGGERS
和 QRTZ_JOB_DETAIL
)。这个前缀实际上可以是任何你想要的,只要你告诉 AdoJobStore 前缀是什么(在你的 Quartz.NET 属性中)。使用不同的前缀可能有助于在同一数据库中为多个调度程序实例创建多组表。
目前,Job Store 内部实现的唯一选择是 JobStoreTX
,它自己创建事务。这与 Quartz 的 Java 版本不同,后者还可以选择使用 J2EE 容器管理事务的 JobStoreCMT
。
难题的最后一块是设置一个数据源,AdoJobStore 可以从该数据源获得与数据库的连接。数据源在您的 Quartz.NET 属性中定义。数据源信息包含连接字符串和 ADO.NET 委托信息。
配置 Quartz 以使用 JobStoreTx
quartz.jobStore.type = Quartz.Impl.AdoJobStore.JobStoreTX, Quartz
接下来,您需要选择一个 IDriverDelegate
实现供 JobStore 使用。 DriverDelegate 负责执行您的特定数据库可能需要的任何 ADO.NET 工作。 StdAdoDelegate
是一个使用“普通”ADO.NET 代码(和 SQL 语句)来完成其工作的委托。 如果没有专门为您的数据库制作的另一个委托,请尝试使用此委托 - 特殊委托通常具有更好的性能或针对数据库特定问题的解决方法。 其他委托可以在 Quartz.Impl.AdoJobStore
命名空间或其子命名空间中找到。
提示
如果你使用默认的 StdAdoDelegate,Quartz.NET 会发出警告,因为当你有很多触发器可供选择时,它的性能很差。 特定的委托有特殊的 SQL 来限制结果集的长度(SqlServerDelegate 使用 TOP n、PostgreSQLDelegate LIMIT n、OracleDelegate ROWCOUNT() <= n 等)。
选择委托后,将其类名设置为 AdoJobStore 使用的委托。
配置 AdoJobStore 以使用 DriverDelegate
quartz.jobStore.driverDelegateType = Quartz.Impl.AdoJobStore.StdAdoDelegate, Quartz
接下来,您需要通知 JobStore 您正在使用什么表前缀(上面讨论过)。
使用表前缀配置 AdoJobStore
quartz.jobStore.tablePrefix = QRTZ_
最后,您需要设置 JobStore 应该使用哪个数据源。 命名数据源也必须在您的 Quartz 属性中定义。 在这种情况下,我们指定 Quartz 应该使用数据源名称“myDS”(在配置属性的其他地方定义)。
使用要使用的数据源的名称配置 AdoJobStore
quartz.jobStore.dataSource = myDS
配置所需的最后一件事是设置数据源连接字符串信息和数据库提供程序。 连接字符串是特定于驱动程序的标准 ADO.NET 连接。 数据库提供程序是数据库驱动程序的抽象,用于在数据库驱动程序和 Quartz 之间创建松散耦合。
设置数据源的连接字符串和数据库提供者
quartz.dataSource.myDS.connectionString = Server=localhost;Database=quartz;Uid=quartznet;Pwd=quartznet
quartz.dataSource.myDS.provider = MySql
目前支持以下数据库提供程序:
SqlServer
- SQL Server 驱动程序- 对于完整的框架,默认情况下是 System.Data.SqlClient(Quartz 3.1 除外)
- 从 Quartz 3.2 开始,.NET Core 默认是 Microsoft.Data.SqlClient
SystemDataSqlClient
- 在 .NET Core 上单独提供(完整框架的默认设置)MicrosoftDataSqlClient
- 在完整框架上单独提供(.NET Core 的默认设置)OracleODP
- Oracle 的 Oracle 驱动程序OracleODPManaged
- 适用于 Oracle 11 的 Oracle 托管驱动程序MySql
- MySQL Connector/.NETSQLite
- SQLite ADO.NET 提供程序SQLite
-Microsoft - Microsoft SQLite ADO.NET 提供程序Firebird
- Firebird ADO.NET 提供程序Npgsql
- PostgreSQL Npgsql
提示
有许多社区贡献的提供者,例如 NoSQL 数据库。
Quartz.NET 项目不支持它们。
如果有更新的驱动程序可用,您可以并且应该使用最新版本的驱动程序,只需创建程序集绑定重定向
如果您的调度程序非常繁忙(即几乎总是执行与线程池大小相同数量的作业,那么您可能应该将数据源中的连接数设置为大约线程池大小 + 1。 这通常在 ADO.NET 连接字符串中配置 - 有关详细信息,请参阅您的驱动程序实现。
quartz.jobStore.useProperties
配置参数可以设置为“true”(默认为 false),以指示 AdoJobStore JobDataMaps 中的所有值都是字符串,因此可以存储为 名称-值 对,而不是存储更复杂的 BLOB 列中的序列化形式的对象。 从长远来看,这更安全,因为您避免了将非字符串类序列化为 BLOB 时存在的类版本控制问题。
将 AdoJobStore 配置为使用字符串作为 JobDataMap 值
提示
这是推荐的配置,因为它大大降低了类型序列化问题的可能性。
quartz.jobStore.useProperties = true
选择序列化程序
Quartz.NET 支持二进制和 JSON 序列化。 JSON 序列化来自单独的 Quartz.Serialization.Json NuGet包。
提示
建议使用 JSON 持久格式来将数据存储在新项目的数据库中。 您还应该强烈考虑将 useProperties 设置为 true 以将键值限制为字符串。
// "json" is alias for "Quartz.Simpl.JsonObjectSerializer, Quartz.Serialization.Json"
quartz.serializer.type = json