在 long 运行 hangfire 进程中发送心跳

Send heartbeat in long running hangfire process

是否可以向hangfire(Redis Storage)发送心跳,告诉系统进程还活着?目前我将 InvisibilityTimeout 设置为 TimeSpan.MaxValue 以防止 hangfire 重新启动作业。但是,如果进程失败或服务器重新启动,该作业将永远不会从 运行 个作业列表中删除。所以我的想法是,删除长时间超时并发送一种心跳代替。这可能吗?

我找到了 https://discuss.hangfire.io/t/hangfire-long-job-stop-and-restart-several-time/4282/2,它涉及如何在 Hangfire 中保持长时间 运行ning 的工作。 User zLanger 表示一旦您...

[...] are hitting hangfire’s invisibilityTimeout. You have two options.

  • increase the timeout to more than the job will ever take to run
  • have the job send a heartbeat to let hangfire’s know it’s still alive.

这对您来说并不陌生。但有趣的是,后续问题是:

How do you implement heartbeat on job?

这里仍然没有答案,这表明您的问题确实不小。

我从来没有在 Hangfire 中处理过长时间的 运行ning 作业,但我从其他排队系统(例如 former SunGrid Engine 知道这个问题,这就是我对您的问题感兴趣的原因。

以前,我遇到过 SunGrid 的问题,该部门的计算机专家告诉我,根据一些数学排队论,应该不惜一切代价避免长时间 运行ning 作业(我会尝试联系他并找到他引用的书的参考资料)。他的想法也许值得与您分享:

如果您有一些作业花费的时间超过了排队系统允许的最大 运行ning 时间,请不要提交作业本身,而是多次调用包装脚本能够 (1) 开始,(2) 冻结停止,(3) 解冻继续实际任务。

这个停止-继续确实可以是操作系统级别的挂起(CTRL+Z 分别是 Linux 中的 fg),参见例如unix.stackexchange.com on that issue

实际上,我有二进制 myMonteCarloExperiment.x 和包装脚本 myMCjobStarter.sh。我的最长计算时间是一天。我会用数百个包装器脚本调用填充队列,边界条件是一次只有一个应该是 运行ning。该脚本将检查是否已经有一个进程 myMonteCarloExperiment.x 在计算集群的任何地方启动,如果没有,它将启动一个实例。如果有一个暂停的进程,包装器脚本会转发它并让它 运行 持续 23 小时 55 分钟,然后暂停该进程。在任何其他情况下,包装器脚本都会报告错误。

这种方法没有实现作业心跳,但它确实 运行 是一项冗长的工作。它还通过避免必须清理 Hangfire 的作业日志来让队列管理员高兴。

更多参考资料

  • 看起来不错