Мы используем Hangfire 1.7.2 в нашем веб-проекте ASP.NET с SQL Server 2016. На нашем сервере около 150 сайтов, каждый из которых использует Hangfire 1.7.2.Мы заметили, что когда мы обновили эти сайты для использования Hangfire, сервер БД рухнул.Проверяя журналы БД, мы обнаружили, что было несколько запросов на блокировку.Мы идентифицировали одно событие RPC «sys.sp_getapplock; 1» во всех сеансах блокировки.Кажется, что Hangfire блокирует нашу БД, делая всю БД непригодной для использования.Мы заметили почти 670+ запросов на блокировку из-за Hangfire.
Это может быть связано с настройкой этих свойств:
SlidingInvisibilityTimeout = TimeSpan.FromMinutes(30),
QueuePollInterval = TimeSpan.FromHours(5)
На каждом сайте есть около 20 фоновых заданий, некоторые из которых выполняютсякаждую минуту, тогда как другие - каждый час, каждые 6 часов, а некоторые - раз в день.
Я искал документацию, но не смог найти ничего, что могло бы объяснить эти два свойства или как их установить, чтобы избежать блокировок БД.
Нужна помощь по этому вопросу.
РЕДАКТИРОВАТЬ: каждую секунду выполняются следующие запросы:
exec sp_executesql N'select count(*) from [HangFire].[Set] with (readcommittedlock, forceseek) where [Key] = @key',N'@key nvarchar(4000)',@key=N'retries'
select distinct(Queue) from [HangFire].JobQueue with (nolock)
exec sp_executesql N'select count(*) from [HangFire].[Set] with (readcommittedlock, forceseek) where [Key] = @key',N'@key nvarchar(4000)',@key=N'retries'
независимо от различных комбинаций значений временного интервала, которые мы установили.Вот код GetHangfirServers, который мы используем:
public static IEnumerable<IDisposable> GetHangfireServers()
{
// Reference for GlobalConfiguration.Configuration: http://docs.hangfire.io/en/latest/getting-started/index.html
// Reference for UseSqlServerStorage: http://docs.hangfire.io/en/latest/configuration/using-sql-server.html#configuring-the-polling-interval
GlobalConfiguration.Configuration
.SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
.UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings()
.UseSqlServerStorage(ConfigurationManager.ConnectionStrings["abc"]
.ConnectionString, new SqlServerStorageOptions
{
CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
SlidingInvisibilityTimeout = TimeSpan.FromMinutes(30),
QueuePollInterval = TimeSpan.FromHours(5), // Hangfire will poll after 5 hrs to check failed jobs.
UseRecommendedIsolationLevel = true,
UsePageLocksOnDequeue = true,
DisableGlobalLocks = true
});
// Reference: https://docs.hangfire.io/en/latest/background-processing/configuring-degree-of-parallelism.html
var options = new BackgroundJobServerOptions
{
WorkerCount = 5
};
var server = new BackgroundJobServer(options);
yield return server;
}
Количество рабочих задано равным 5.
Есть только 4 задания, и даже они выполнены (ВЫБРАТЬ * ОТ [HangFire]. [State]):
У вас есть идея, почему Hangfire выполняет так много запросов в секунду?