我有一个用 .NET 8 编写并托管在 IIS 上的 Hangfire 应用程序。它用于运行每日计划作业。 问题是,一段时间后,应用程序关闭并且不再启动,因此作业无法运行。
我做了 Hangfire 文档部分中的所有操作“如果没有什么对你有用......,但它仍然不起作用。我回收应用程序池/重新启动,但应用程序不会再次启动。
IIS:
installed Application Initialization module
应用程序池:
set .NET CLR version to 4.0
set managed pipeline mode to 4.0
set start mode to AlwaysRunning
set Idle Time-Out (minutes) to 0
站点:
set Preload Enabled to true
Configuration Manager → system.webServer/applicationInitialization
From: ApplicationHost.config
set doAppInitAfterRestart to True
added hostName and initializationPage to Collection Editor
我错过了什么?
Windows Server 2019,IIS 版本 10。
您应该将 Hangfire 服务器托管在不同的应用程序中 - 例如 Windows 服务。并使用 Web API 来托管 Hangfire 仪表板。
设置看起来像这样:
对于 Windows 服务:
var hostbuilder = Host.CreateDefaultBuilder(args);
var host = hostbuilder.UseWindowsService().
ConfigureServices((hostContext, services) =>
{
var storageOptions = new SqlServerStorageOptions
{
CommandBatchMaxTimeout = TimeSpan.FromMinutes(30),
SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
QueuePollInterval = TimeSpan.Zero,
UseRecommendedIsolationLevel = true,
DisableGlobalLocks = true,
EnableHeavyMigrations = true,
};
services.AddHangfire(c => c
.UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings()
.UseSqlServerStorage(() => new SqlConnection(connectionString), storageOptions));
services.AddHangfireServer(a =>
{
a.WorkerCount = Math.Min(Environment.ProcessorCount * hangfireConfiguration.WorkerCount, 10);
a.Queues = new[] { "default", "lowprio" };
});
}).Build();
await host.RunAsync();
对于 Web API,您只需配置 Hangfire 仪表板,使用上面相同的代码,无需添加 Hangfire 服务器。
类似这样的:
var builder = WebApplication.CreateBuilder(args);
var storageOptions = new SqlServerStorageOptions
{
CommandBatchMaxTimeout = TimeSpan.FromMinutes(30),
SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
QueuePollInterval = TimeSpan.Zero,
UseRecommendedIsolationLevel = true,
PrepareSchemaIfNecessary = false
};
builder.Services..AddHangfire(c => c
.UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings()
.UseSqlServerStorage(() => new SqlConnection(connectionString), storageOptions));
var app = builder.Build();
var hangfireStorage = new SqlServerStorage(() => new SqlConnection(connectionString), storageOptions);
var dashboardOptions = new DashboardOptions { Authorization = new[] { new AllowAllAuthorizationFilter() } };
app.UseHangfireDashboard("/dashboard", dashboardOptions, hangfireStorage);
await app.RunAsync();
}
public class AllowAllAuthorizationFilter : IDashboardAuthorizationFilter
{
public bool Authorize(DashboardContext context)
{
return true;
}
}
PS 不要忘记使用相同的连接字符串。您的服务器和仪表板将查看同一个数据库。
在 IIS 上实现始终开启确实具有挑战性,并且取决于很多因素 - 这种方式要容易得多 - widows 服务始终运行。