加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net – 如何防止Hangfire重复作业在连续执行30分钟后重新启

发布时间:2020-12-16 07:36:25 所属栏目:asp.Net 来源:网络整理
导读:我正在使用asp.net mvc-5 Web应用程序,我在使用Hangfire工具运行长时间运行的后台作业时遇到了问题.问题是如果作业执行超过30分钟,那么hangfire会自动启动另一个作业,所以我最终会同时运行两个类似的作业. 现在我有以下内容: – Asp.net mvc-5 IIS-8 Hangfi
我正在使用asp.net mvc-5 Web应用程序,我在使用Hangfire工具运行长时间运行的后台作业时遇到了问题.问题是如果作业执行超过30分钟,那么hangfire会自动启动另一个作业,所以我最终会同时运行两个类似的作业.

现在我有以下内容: –

> Asp.net mvc-5
> IIS-8
> Hangfire 1.4.6
> Windows Server 2012

现在我已经定义了一个每天17:00运行的篝火重复工作.后台作业主要扫描我们的网络中的服务器和虚拟机并更新数据库,定期作业将在完成执行后发送电子邮件.
经常性工作在执行时间不到30分钟时效果很好.但是今天随着我们的系统的发展,经常性的工作在40分钟后完成,而不是像过去那样在22-25分钟之后完成.我收到了2封电子邮件,而不是一封电子邮件(电子邮件之间的时间约为30分钟).现在我手动重新运行这个工作,我注意到问题如下: –

“when the recurring job reaches 30 minutes of continuous execution,a
new instance of the recurring job will start,so I will have two
instances instead of one running at the same time,so that why I received 2 emails.”

现在,如果定期工作不到30分钟(例如29分钟),我将不会遇到任何问题,但如果重复执行的工作超过30分钟,那么由于某种原因或其他原因,将启动新工作.
虽然当我在执行作业期间访问hangfire仪表板时,我发现只有一个活动作业,当我监视我的数据库时,我可以从sql profiler看到有两个作业访问数据库.这种情况发生在经常性工作开始30分钟后(在我们的案例中是17:30),这就是为什么我收到2封电子邮件,这意味着2个重复工作在后台运行而不是一个.

那么有人可以提出这方面的建议吗,如果目前的重复工作执行时间超过30分钟,我怎么能避免因自动启动新的定期工作而导致绞火?
谢谢

解决方法

您是否看过 Hangfire docs的InvisibilityTimeout设置?

Default SQL Server job storage implementation uses a regular table as
a job queue. To be sure that a job will not be lost in case of
unexpected process termination,it is deleted only from a queue only
upon a successful completion.

To make it invisible from other workers,the UPDATE statement with
OUTPUT clause is used to fetch a queued job and update the FetchedAt
value (that signals for other workers that it was fetched) in an
atomic way. Other workers see the fetched timestamp and ignore a job.
But to handle the process termination,they will ignore a job only
during a specified amount of time (defaults to 30 minutes).

Although this mechanism ensures that every job will be processed,
sometimes it may cause either long retry latency or lead to multiple
job execution. Consider the following scenario:

  1. Worker A fetched a job (runs for a hour) and started it at 12:00.
  2. Worker B fetched the same job at 12:30,because the default invisibility timeout was expired.
  3. Worker C (did not fetch) the same job at 13:00,because (it
    will be deleted after successful performance.)

If you are using cancellation tokens,it will be set for Worker A at
12:30,and at 13:00 for Worker B. This may lead to the fact that your
long-running job will never be executed. If you aren’t using
cancellation tokens,it will be concurrently executed by WorkerA and
Worker B (since 12:30),but Worker C will not fetch it,because it
will be deleted after successful performance.

So,if you have long-running jobs,it is better to configure the
invisibility timeout interval:

var options = new SqlServerStorageOptions
{
    InvisibilityTimeout = TimeSpan.FromMinutes(30) // default value
};

GlobalConfiguration.Configuration.UseSqlServerStorage("<name or connection string>",options);

截至Hangfire 1.5 this option is now Obsolete年.正在开展工作的工作对其他工人来说是不可见的.

Say goodbye to confusing invisibility timeout with unexpected
background job retries after 30 minutes (by default) when using SQL
Server. New Hangfire.SqlServer implementation uses plain old
transactions to fetch background jobs and hide them from other
workers.

Even after ungraceful shutdown,the job will be available for other workers instantly,without any delays.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读