SQL Server 是 Hangfire 的默认存储-它被许多 .NET 开发人员所熟知,并在许多项目环境中使用。有趣的是,在Hangfire 开发的早期阶段,Redis 用于存储有关作业的信息,而 SQL Server 存储实现则受到了这种 NoSQL 解决方案的启发。

支持的数据库驱动

Microsoft SQL Server 2008R2(任何版本,包括LocalDB)及更高版本、 Microsoft SQL Azure 。

安装

SQL Server 存储实现通过 Hangfire.SqlServer NuGet 包提供。要安装它,您可以修改 *.csproj 文件以包含以下行,或者仅通过 NuGet 包管理器进行安装。

  1. <ItemGroup>
  2. <PackageReference Include="Hangfire.SqlServer" Version="1.8.*" />
  3. </ItemGroup>

这个包是 Hangfire 引导程序包 Hangfire 的依赖项,因此,如果您已经安装了它,就不需要单独安装Hangfire.SqlServer -它已经被添加到您的项目中。

Microsoft.Data.SqlClient

Hangfire.SqlServer 1.8 版本的包没有显式引用 System.Data.SqlClient 包,以避免使用过时的版本,并在应用程序的其他部分安装和使用 Microsoft.Data.SqlClient 包时默认使用它。

  1. <ItemGroup>
  2. <PackageReference Include="Microsoft.Data.SqlClient" Version="*">
  3. </ItemGroup>

System.Data.SqlClient

假设出于兼容性原因,您更喜欢保留以前的 SQL 客户端包。在这种情况下,您可以显式引用它并确保SqlClientFactory 指向它,以防任何其他包导致安装 Microsoft.Data.SqlClient ,如下所示。

  1. <ItemGroup>
  2. <PackageReference Include="System.Data.SqlClient" Version="*">
  3. </ItemGroup>

显式配置

Hangfire 将尝试自动确定要使用的包,具体取决于实际安装的包。如果安装了两个包,则Microsoft.Data.SqlClient 将被优先选择,但您可以通过使用 SqlServerStorageOptions 类的SqlClientFactory 属性来指定要选择哪个包。

  1. GlobalConfiguration.Configuration
  2. .UseSqlServerStorage("connection_string", new SqlServerStorageOptions
  3. {
  4. SqlClientFactory = System.Data.SqlClient.SqlClientFactory
  5. // or
  6. SqlClientFactory = Microsoft.Data.SqlClient.SqlClientFactory
  7. });

配置

该包为 GlobalConfiguration 类提供扩展方法。如果您有 SQL Server 的连接字符串或连接字符串名称,请选择一个。

  1. GlobalConfiguration.Configuration
  2. // Use connection string name defined in `web.config` or `app.config`
  3. .UseSqlServerStorage("db_connection")
  4. // Use custom connection string
  5. .UseSqlServerStorage(@"Server=.\sqlexpress; Database=Hangfire; Integrated Security=SSPI;");

Hangfire 1.8

Hangfire.SqlServer 包的最新版本现在尝试根据当前架构版本使用建议的选项。它在 SqlServerStorage 类实例初始化时查询当前架构版本,并自动设置相应的选项。如果您希望在启动期间避免进行网络调用,则可以以以下方式禁用此行为。

  1. GlobalConfiguration.Configuration
  2. .UseSqlServerStorage("db_connection", new SqlServerStorageOptions
  3. {
  4. TryAutoDetectSchemaDependentOptions = false // Defaults to `true`
  5. });

Hangfire 1.7

从 1.7.0 版本开始,建议为新安装设置以下选项(对于现有选项,请参阅升级到 Hangfire 1.7)。这些设置将在 2.0 中默认打开,但同时我们应该保持向后兼容性。

  1. GlobalConfiguration.Configuration
  2. .UseSqlServerStorage("db_connection", new SqlServerStorageOptions
  3. {
  4. CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
  5. SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
  6. QueuePollInterval = TimeSpan.Zero,
  7. UseRecommendedIsolationLevel = true,
  8. DisableGlobalLocks = true // Migration to Schema 7 is required
  9. });

安装对象

Hangfire 利用几张表和索引来持久化后台作业和其他与处理相关的信息: 使用 SQL Server - 图1

其中一些表用于核心功能,其他表满足可扩展性需求(使得可以在不更改底层架构的情况下编写扩展)。为了保持尽可能简单并允许与SQL Azure一起使用库,不会使用高级对象如存储过程、触发器等。

SQL Server 对象通过执行位于 NuGet 包中 tools 文件夹下的 Install.sql 文件中描述的语句,从SqlServerStorage 构造函数中自动安装。该文件包含迁移脚本,因此可以无缝安装具有架构更改的 Hangfire 新版本,而无需您的干预。

如果您想手动安装对象,或将其与现有的迁移子系统集成,请通过 SQL Server 存储选项传递您的决定:

  1. var options = new SqlServerStorageOptions
  2. {
  3. PrepareSchemaIfNecessary = false
  4. };
  5. GlobalConfiguration.Configuration.UseSqlServerStorage("<name or connection string>", options);

您可以将 HangFire 数据库访问隔离到仅 HangFire 架构。您需要创建一个单独的 HangFire 用户,并授予该用户仅访问 HangFire 架构的权限。 HangFire 用户将只能更改 HangFire 架构。以下是一个使用包含的数据库用户进行HangFire 的示例。 HangFire 用户具有所需的最低权限,但仍然允许它将来正确升级架构。

  1. CREATE USER [HangFire] WITH PASSWORD = 'strong_password_for_hangfire'
  2. GO
  3. IF NOT EXISTS (SELECT 1 FROM sys.schemas WHERE [name] = 'HangFire') EXEC ('CREATE SCHEMA [HangFire]')
  4. GO
  5. ALTER AUTHORIZATION ON SCHEMA::[HangFire] TO [HangFire]
  6. GO
  7. GRANT CREATE TABLE TO [HangFire]
  8. GO

配置轮询间隔

原始 SQL Server 作业存储实现的主要缺点之一是它使用轮询技术来获取新作业。从 Hangfire 1.7.0 开始,当设置了 SlidingInvisibilityTimeout 选项时,可以使用 TimeSpan.Zero 作为轮询间隔。

  1. var options = new SqlServerStorageOptions
  2. {
  3. SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
  4. QueuePollInterval = TimeSpan.Zero
  5. };
  6. GlobalConfiguration.Configuration.UseSqlServerStorage("<name or connection string>", options);

这是该版本中的推荐值,但如果您的后台作业可以在调用之前容忍额外的延迟,则可以减小轮询间隔。