Hangfire服务器正在尝试从其他队列处理作业

时间:2018-04-25 20:24:13

标签: c# hangfire

我想问一下如何定义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&amp; 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)"

1 个答案:

答案 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;
    }