我想问一下如何定义HangFire服务器不应该处理重复的工作?
有两个应用程序(Windows服务和Web应用程序)使用HangFire运行后台作业,因此有两个hangfire服务器(队列已正确定义)。
服务仅创建定期作业,并且正在使用“默认”队列。 Web应用程序创建了即发即弃的作业,并且正在使用其他队列(例如web_app_queue)。
似乎由Web应用程序创建的HangFire服务器正在尝试安排/处理定期作业,尽管已为其他队列定义,但Web应用程序HangFire服务器无法访问可用于Windows服务的所需程序集。
Web App HangFire服务器:
var backgroundJobServer = new BackgroundJobServer(new BackgroundJobServerOptions { Queues = new[] { "web_app_queue" } });
Web App HangFire作业:
var client = new BackgroundJobClient();
var state = new EnqueuedState("web_app_queue");
var jobId = client.Create(methodCall, state);
Windows服务HangFire服务器:
var server = new BackgroundJobServer();
Windows服务HangFire作业:
private static void AddRecurringJob<T>(string cronExpression) where T : IJob
{
RecurringJob.AddOrUpdate<T>(job => job.Execute(), cronExpression, TimeZoneInfo.Local);
}
未为Windows服务HangFire服务器和作业定义队列名称,因此应用默认队列(“default”)。
此处有异常消息和详细信息:
message="Recurring job ... can not be scheduled due to job load exception."
detail="Hangfire.Common.JobLoadException: Could not load the job. See inner exception for the details.
---> System.IO.FileNotFoundException: Could not load file or assembly 'XXX.YYY, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.;
at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMarkHandle stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartialName, ObjectHandleOnStack type);
at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartialName);
at System.Type.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase);
at Hangfire.Storage.InvocationData.Deserialize();
--- End of inner exception stack trace
at Hangfire.Storage.InvocationData.Deserialize();
at Hangfire.Server.RecurringJobScheduler.TryScheduleJob(JobStorage storage, IStorageConnection connection, String recurringJobId, IReadOnlyDictionary`2 recurringJob);
at Hangfire.Server.RecurringJobScheduler.Execute(BackgroundProcessContext context)"
答案 0 :(得分:1)
我在这里找到了解决问题的方法:https://github.com/HangfireIO/Hangfire/issues/775
因此,可以创建HangFire服务器(使用类BackgroundProcessingServer)并定义此服务器可以处理哪些进程。
通过这种方式,我能够定义我的网络应用HangFire服务器应该只处理即发即弃的流程
示例:
int workerCount = Environment.ProcessorCount * 5;
string queueName = "web_app_queue";
List<IBackgroundProcess> processes = GetProcessesForBackgroundServer(queueName, workerCount);
var backgroundJobServer = new BackgroundProcessingServer(JobStorage.Current, processes, new Dictionary<string, object> { { "Queues", new string[] { queueName } }, { "WorkerCount", workerCount } });
private List<IBackgroundProcess> GetProcessesForBackgroundServer(string queueName, int workerCount)
{
var processes = new List<IBackgroundProcess>();
for (var i = 0; i < workerCount; i++)
{
processes.Add(new Worker(queueName)); //only fire-and-forgot jobs will be processed by this server (important processes ServerHeartbeat, ServerWatchdog are included automatically by BackgroundProcessingServer)
};
return processes;
}