是什么导致 azure 托管的hangfire 作业出现这样的行为?

dyl*_*anT 5 azure hangfire

重复性工作计划

一段时间以来,我一直遇到两个重复性作业(位于此列表顶部的作业)的麻烦,即使它们已安排,但它们也无法运行。

我可以很好地触发它们,并且它们会被重新安排,但是当计划时间到来时,它们不会运行,并且“下一次执行”时间就会过去。

现在还有很多其他工作也面临着同样的问题。这些应该每小时运行一次,但如果超过了计划时间,它们就不会运行。

访问仪表板没有什么区别。网络应用程序始终处于开启状态。Hangfire 永远不会运行这些作业,除非我手动触发它们。不处于这种状态的作业仍然每天或每小时按计划正常运行。

什么会导致这种情况呢?

我的hangfire 实例(版本1.7.6)位于设置为始终运行的Azure WebApp 中。看,它一直在运行!它使用 Azure-sql 数据库作为其数据存储。

这是我的 Bootstrapper.cs 代码:

using System.Configuration;
using System.Web.Hosting;
using Hangfire;

namespace MyApi
{
    public class HangfireBootstrapper : IRegisteredObject
    {
        public static readonly HangfireBootstrapper Instance = new HangfireBootstrapper();

        private readonly object _lockObject = new object();
        private bool _started;

        private BackgroundJobServer _backgroundJobServer;

        private HangfireBootstrapper()
        {
        }

        public void Start()
        {
            lock (_lockObject)
            {
                if (_started) return;
                _started = true;

                HostingEnvironment.RegisterObject(this);
                var jobOptions = new BackgroundJobServerOptions();
                jobOptions.ServerName = ConfigurationManager.AppSettings.Get("hangfire:servername");
                jobOptions.Queues = new[] {"k1"};

                GlobalConfiguration.Configuration
                    .UseSqlServerStorage("Kdb");

                _backgroundJobServer = new BackgroundJobServer(jobOptions);
            }
        }

        public void Stop()
        {
            lock (_lockObject)
            {
                if (_backgroundJobServer != null)
                {
                    _backgroundJobServer.Dispose();
                }

                HostingEnvironment.UnregisterObject(this);
            }
        }

        void IRegisteredObject.Stop(bool immediate)
        {
            Stop();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

以下是用于对大多数作业进行排队的代码:

jobMgr.AddOrUpdate($"Script.{i1}.{name}", Job.FromExpression(() => HangfireJobs.ReplayQueue.EnqueueScript(scriptId, i1, null)),cronExpression);
Run Code Online (Sandbox Code Playgroud)

以下是我的 EnqueueScript 方法的定义方式:

    [Queue("k1")]
    public static void EnqueueScript(Guid scriptId, int env, PerformContext context)
    {
        try
        {
           ...
Run Code Online (Sandbox Code Playgroud)

dyl*_*anT 0

此问题已通过将 Hangfire 升级到版本 1.7.8 得到解决。

Hangfire 错误报告可在https://github.com/HangfireIO/Hangfire/issues/1459查看

它似乎是在 1.7.4 版本左右引入的(可能更早,但肯定是在那时),并在 1.7.8 版本中修复。