Azure Webjob计时器触发器未触发。

3
我们有两个部署(Prod和Test)在Azure Webjob中运行,使用TimerTrigger。这两个Web应用程序只有一个实例。根据这篇文章,TimeTriggers使用单例锁定来确保没有并发调用。这两个实例使用相同的存储帐户。我们面临的问题是其中一个部署似乎只能获取锁定,而另一个无法获取锁定。如果我们停止第一个WebJob,则第二个会获取锁并开始处理,反之亦然。
锁是否依赖于存储帐户?如何确保这两个部署具有单独的锁定机制并同时运行?
3个回答

15

你说得对,你需要使用不同的存储帐户。

根据文档:

在幕后,TimerTrigger使用WebJobs SDK的Singleton功能,以确保您的触发函数仅在任何给定时间运行一个实例。 当JobHost启动时,为每个TimerTrigger函数都会获取一个Blob租赁(单例锁)。此分布式锁定可确保仅在任何时候运行一个计划函数的实例。如果当前未租用该函数的Blob,则该函数将获取租用并立即按计划开始运行。 如果无法获取Blob租赁,则通常意味着该函数的另一个实例正在运行,因此该函数不会在当前主机上启动。发生这种情况时,主机将继续定期检查是否可以获取租约。这是一种“恢复”模式,以确保在运行稳态时,如果一个实例关闭,另一个实例会注意到并继续之前的工作。

如果您查看锁定机制的实现(StorageScheduleMonitor.cs):
  • 作业在容器内获取锁定(blob)。
  • 该 blob 位于特定目录中(基于 HostId)。
  • blob 的名称不可配置。
因此,根据 @volodymyr-bilyachat 的回答,有两种可能性:
  • Having separated storage accounts: makes sense if you have a storage account per environment (dev/staging/prod)

  • Specifying the HosId property of the JobHostConfiguration class:

    var config = new JobHostConfiguration();
    config.HostId = "dev|staging|prod";
    

“Blob lease” 是指存储范围锁吗?我觉得这不合理,一个单一的锁用于多个部署。 - Abhay Kumar
更新了我的回答。 - Thomas

3

使用不同的存储账户或设置主机

var config = new JobHostConfiguration();
config.HostId = "dev|prod"
var host = new JobHost(config);
host.RunAndBlock();

你确定 HostId 是正确的吗?似乎这更多与扩展相关。 - Thomas
@Thomas 当我在开发和暂存阶段使用相同的存储时,我也遇到了同样的问题。这对我很有帮助。 - Vova Bilyachat
好的,知道了 :-) 当我遇到这个问题时,我创建了不同的存储账户。 - Thomas
@Thomas 好了,现在我也不用使用相同的存储帐户了:) 最终,在本地我使用仿真器,在 Azure 上每个环境都有自己的存储。 - Vova Bilyachat
@Thomas 为了确保,请查看此处 https://github.com/Azure/azure-webjobs-sdk/blob/master/src/Microsoft.Azure.WebJobs.Host/JobHostConfiguration.cs - Vova Bilyachat
1
好的,我看了这里的代码:https://github.com/Azure/azure-webjobs-sdk-extensions/blob/master/src/WebJobs.Extensions/Extensions/Timers/Scheduling/StorageScheduleMonitor.cs。所以是的,hostid对锁有影响。 - Thomas

0

如果您使用TimerTrigger,请确保在Web应用程序上启用了Always On。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接