Hangfire 服务器正在尝试处理来自其他队列的作业
Hangfire server is trying to process job from other queue
我想问问有没有办法定义 HangFire 服务器不应该处理重复作业?
有两个应用程序(windows 服务和 Web 应用程序)使用 HangFire 进行 运行 后台作业,因此有两个 hangfire 服务器(队列定义正确)。
服务仅创建重复作业,并且它正在使用 "default" 队列。
Web 应用程序创建即发即弃作业,并且它正在使用其他队列(例如 web_app_queue)。
似乎由 Web 应用程序创建的 HangFire 服务器正在尝试 schedule/process 重复作业,尽管已为其他队列定义,但 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)"
我在这里找到了问题的解决方案:https://github.com/HangfireIO/Hangfire/issues/775
因此可以创建 HangFire 服务器(使用 class BackgroundProcessingServer)并定义该服务器可以处理哪些进程。
这样我就可以定义我的 Web 应用程序 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;
}
我想问问有没有办法定义 HangFire 服务器不应该处理重复作业?
有两个应用程序(windows 服务和 Web 应用程序)使用 HangFire 进行 运行 后台作业,因此有两个 hangfire 服务器(队列定义正确)。
服务仅创建重复作业,并且它正在使用 "default" 队列。 Web 应用程序创建即发即弃作业,并且它正在使用其他队列(例如 web_app_queue)。
似乎由 Web 应用程序创建的 HangFire 服务器正在尝试 schedule/process 重复作业,尽管已为其他队列定义,但 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)"
我在这里找到了问题的解决方案:https://github.com/HangfireIO/Hangfire/issues/775
因此可以创建 HangFire 服务器(使用 class BackgroundProcessingServer)并定义该服务器可以处理哪些进程。
这样我就可以定义我的 Web 应用程序 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;
}