我使用 .NET Core 附带的 Windows Hosting 模块在 IIS 下运行 ASP.NET Core API (v 2.2)。我已经在 startup.cs 中配置了 Hangfire,其中包含几个重复的作业。
由于不活动,API 的应用程序池会定期回收。但是,每当应用程序池被回收(出于任何原因)时,循环作业就会停止运行,直到第一个用户调用 api。
Hangfire 文档有解决方案,但它特定于 Full .NET,可能不适用于 .NET Core。
我找到的解决方案之一是在控制台应用程序中运行重复性作业,但随后我必须创建和维护另一个应用程序。此外,除了重复性作业之外,API 在内部还会创建后台作业以进行单向调用。例如
[HttpPost]
public IActionResult DoWork(int id)
{
BackgroundJob.Enqueue<IWorkerService>(x => x.DoWork(id));
}
Run Code Online (Sandbox Code Playgroud)
因此,如果我仅为重复性作业创建控制台应用程序,我仍然必须在 API 中为后台作业配置 Hangfire。我试图避免在两个地方配置 Hangfire。
我在 ASP.NET Core 中有哪些选项可以让 API 始终运行?
设置Regular Time Interval为 0
我会等几天看看这个设置是如何工作的
但是,我不确定不回收应用程序池是否是个好主意?任何建议
hangfire asp.net-core asp.net-core-webapi asp.net-core-2.1 hangfire-sql
要重新安排计划的作业,我目前正在删除以前的作业,然后在事务中安排新的作业,因此如果计划失败,它会回滚删除:
using (var transaction = new TransactionScope(TransactionScopeOption.Required))
{
BackgroundJob.Delete(jobId);
BackgroundJob.Schedule(...);
}
Run Code Online (Sandbox Code Playgroud)
这涉及将原始参数保存在某处,以便我可以使用原始参数重新安排时间。
我想知道执行以下操作是否有任何后果:
new BackgroundJobClient().ChangeState(jobId, new ScheduledState(timespan), ScheduledState.StateName);
Run Code Online (Sandbox Code Playgroud)
这样就不需要保留原始的工作参数并且也是事务性的。
我遇到一个问题,hangfire 上的某些作业使用相同的参数排队不止一次,这些作业几乎同时排队。
我尝试将工作人员的数量限制为一名,然后用DisableConcurrentExecution.
我使用 sqlserver 作为存储。有人遇到过这个问题吗?有一些技巧可以避免吗?
PS:我DisableConcurrentExecution之所以使用它,是因为在hangfire文档中说互斥体和信号量不能保证该作业仅被调用一次。
PS2:检查我的hangfire 服务器,我注意到我有两个实例,每个实例有 1 个工作人员,所以我认为这是一个并行问题而不是并发问题。
我们正在尝试在 ASP.NET Core WebApi 应用程序 (.NET 5) 中首次使用 Hangfire (v1.7.19)。以前它们都是老式的 ASP.NET,并且运行没有问题。
使用的 Hangfire 软件包(根据Hangfire 文档)是Hangfire.Core、Hangfire.SqlServer和Hangfire.AspNetCore。我们也尝试过仅使用组合Hangfire包,但得到了相同的结果。
直接从该文档页面上的代码中提取,在ConfigureServices中我们添加
services.AddHangfire(configuration => configuration
.SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
.UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings()
.UseSqlServerStorage(connectionString), new SqlServerStorageOptions
{
CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
QueuePollInterval = TimeSpan.Zero,
UseRecommendedIsolationLevel = true,
DisableGlobalLocks = true
}));
Run Code Online (Sandbox Code Playgroud)
在运行时,给出
System.ArgumentException
HResult=0x80070057
Message=Keyword not supported: 'authentication'.
Source=System.Data.SqlClient
StackTrace:
at System.Data.Common.DbConnectionOptions.ParseInternal(Dictionary`2 parsetable, String connectionString, Boolean buildChain, Dictionary`2 synonyms)
at System.Data.Common.DbConnectionOptions..ctor(String connectionString, Dictionary`2 synonyms)
at System.Data.SqlClient.SqlConnectionString..ctor(String connectionString)
at System.Data.SqlClient.SqlConnectionFactory.CreateConnectionOptions(String …Run Code Online (Sandbox Code Playgroud) azure-active-directory hangfire azure-sql-database asp.net-core-webapi hangfire-sql
我们有多个网络服务器运行我们的网站,并带有负载平衡器,因此根据负载将用户定向到不同的服务器。每台服务器上的每个实例的代码都是相同的,并且我们有运行的重复作业。显然我们不希望作业同时在两台服务器上运行。
当作业运行时,hangfire 是否会实施锁定,以便它不会自动再次运行?
目前我们已经在每个运行的方法上都有这个[Hangfire.DisableConcurrentExecution(60 * 60 * 5)],这会阻止两台服务器同时运行代码吗?