SQL Server 是 Hangfire 的默认存储-它被许多 .NET 开发人员所熟知,并在许多项目环境中使用。有趣的是,在Hangfire 开发的早期阶段,Redis 用于存储有关作业的信息,而 SQL Server 存储实现则受到了这种 NoSQL 解决方案的启发。
支持的数据库驱动
Microsoft SQL Server 2008R2(任何版本,包括LocalDB)及更高版本、 Microsoft SQL Azure 。
安装
SQL Server 存储实现通过 Hangfire.SqlServer NuGet 包提供。要安装它,您可以修改 *.csproj
文件以包含以下行,或者仅通过 NuGet 包管理器进行安装。
<ItemGroup>
<PackageReference Include="Hangfire.SqlServer" Version="1.8.*" />
</ItemGroup>
这个包是 Hangfire 引导程序包 Hangfire 的依赖项,因此,如果您已经安装了它,就不需要单独安装Hangfire.SqlServer -它已经被添加到您的项目中。
Microsoft.Data.SqlClient
Hangfire.SqlServer 1.8 版本的包没有显式引用 System.Data.SqlClient 包,以避免使用过时的版本,并在应用程序的其他部分安装和使用 Microsoft.Data.SqlClient 包时默认使用它。
<ItemGroup>
<PackageReference Include="Microsoft.Data.SqlClient" Version="*">
</ItemGroup>
System.Data.SqlClient
假设出于兼容性原因,您更喜欢保留以前的 SQL 客户端包。在这种情况下,您可以显式引用它并确保SqlClientFactory
指向它,以防任何其他包导致安装 Microsoft.Data.SqlClient
,如下所示。
<ItemGroup>
<PackageReference Include="System.Data.SqlClient" Version="*">
</ItemGroup>
显式配置
Hangfire 将尝试自动确定要使用的包,具体取决于实际安装的包。如果安装了两个包,则Microsoft.Data.SqlClient
将被优先选择,但您可以通过使用 SqlServerStorageOptions 类的SqlClientFactory 属性来指定要选择哪个包。
GlobalConfiguration.Configuration
.UseSqlServerStorage("connection_string", new SqlServerStorageOptions
{
SqlClientFactory = System.Data.SqlClient.SqlClientFactory
// or
SqlClientFactory = Microsoft.Data.SqlClient.SqlClientFactory
});
配置
该包为 GlobalConfiguration 类提供扩展方法。如果您有 SQL Server 的连接字符串或连接字符串名称,请选择一个。
GlobalConfiguration.Configuration
// Use connection string name defined in `web.config` or `app.config`
.UseSqlServerStorage("db_connection")
// Use custom connection string
.UseSqlServerStorage(@"Server=.\sqlexpress; Database=Hangfire; Integrated Security=SSPI;");
Hangfire 1.8
Hangfire.SqlServer 包的最新版本现在尝试根据当前架构版本使用建议的选项。它在 SqlServerStorage 类实例初始化时查询当前架构版本,并自动设置相应的选项。如果您希望在启动期间避免进行网络调用,则可以以以下方式禁用此行为。
GlobalConfiguration.Configuration
.UseSqlServerStorage("db_connection", new SqlServerStorageOptions
{
TryAutoDetectSchemaDependentOptions = false // Defaults to `true`
});
Hangfire 1.7
从 1.7.0 版本开始,建议为新安装设置以下选项(对于现有选项,请参阅升级到 Hangfire 1.7)。这些设置将在 2.0 中默认打开,但同时我们应该保持向后兼容性。
GlobalConfiguration.Configuration
.UseSqlServerStorage("db_connection", new SqlServerStorageOptions
{
CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
QueuePollInterval = TimeSpan.Zero,
UseRecommendedIsolationLevel = true,
DisableGlobalLocks = true // Migration to Schema 7 is required
});
安装对象
Hangfire 利用几张表和索引来持久化后台作业和其他与处理相关的信息:
其中一些表用于核心功能,其他表满足可扩展性需求(使得可以在不更改底层架构的情况下编写扩展)。为了保持尽可能简单并允许与SQL Azure一起使用库,不会使用高级对象如存储过程、触发器等。
SQL Server 对象通过执行位于 NuGet 包中 tools 文件夹下的 Install.sql 文件中描述的语句,从SqlServerStorage 构造函数中自动安装。该文件包含迁移脚本,因此可以无缝安装具有架构更改的 Hangfire 新版本,而无需您的干预。
如果您想手动安装对象,或将其与现有的迁移子系统集成,请通过 SQL Server 存储选项传递您的决定:
var options = new SqlServerStorageOptions
{
PrepareSchemaIfNecessary = false
};
GlobalConfiguration.Configuration.UseSqlServerStorage("<name or connection string>", options);
您可以将 HangFire 数据库访问隔离到仅 HangFire 架构。您需要创建一个单独的 HangFire 用户,并授予该用户仅访问 HangFire 架构的权限。 HangFire 用户将只能更改 HangFire 架构。以下是一个使用包含的数据库用户进行HangFire 的示例。 HangFire 用户具有所需的最低权限,但仍然允许它将来正确升级架构。
CREATE USER [HangFire] WITH PASSWORD = 'strong_password_for_hangfire'
GO
IF NOT EXISTS (SELECT 1 FROM sys.schemas WHERE [name] = 'HangFire') EXEC ('CREATE SCHEMA [HangFire]')
GO
ALTER AUTHORIZATION ON SCHEMA::[HangFire] TO [HangFire]
GO
GRANT CREATE TABLE TO [HangFire]
GO
配置轮询间隔
原始 SQL Server 作业存储实现的主要缺点之一是它使用轮询技术来获取新作业。从 Hangfire 1.7.0 开始,当设置了 SlidingInvisibilityTimeout 选项时,可以使用 TimeSpan.Zero 作为轮询间隔。
var options = new SqlServerStorageOptions
{
SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
QueuePollInterval = TimeSpan.Zero
};
GlobalConfiguration.Configuration.UseSqlServerStorage("<name or connection string>", options);
这是该版本中的推荐值,但如果您的后台作业可以在调用之前容忍额外的延迟,则可以减小轮询间隔。