3

我们有两个使用 TimerTrigger 运行的 Azure Webjob 部署(产品和测试)。这两个 Web 应用程序都有一个实例。根据这篇文章,TimeTriggers 使用单例锁来确保没有并行调用。这两个实例使用相同的存储帐户。我们面临的问题是,似乎只有一个部署获得了锁,而其他部署无法获得锁。如果我们停止第一个 webjob,第二个 webjob 将获取锁并开始处理,反之亦然。

锁定是否取决于存储帐户?我们如何确保这两个部署都有单独的锁定机制并同时运行?

4

3 回答 3

15

没错,您必须使用不同的存储帐户。

文档中:

在幕后,TimerTrigger使用 WebJobs SDK 的Singleton特性来确保在任何给定时间只有一个触发函数实例在运行。当 JobHost 启动时,您的每个 TimerTrigger 函数都会使用一个 blob 租约(单例锁)。这种分布式锁确保在任何时候只有一个计划函数的实例在运行。如果该函数的 blob 当前未租用,则该函数将获取租约并立即开始按计划运行。如果无法获取 blob 租约,一般意味着该函数的另一个实例正在运行,因此该函数未在当前主机中启动. 发生这种情况时,主机将继续定期检查是否可以获取租约。这是作为一种“恢复”模式完成的,以确保在运行稳定状态时,如果一个实例出现故障,另一个实例会注意到并从另一个停止的地方接起。

如果您查看锁定机制的实现(StorageScheduleMonitor.cs):

  • 该作业在容器内获取锁(blob)。
  • Blob 位于特定目录中(基于 HostId)。
  • blob 的名称不可配置。

因此,基于@volodymyr-bilyachat 的回答,有两种可能性:

  • 拥有单独的存储帐户:如果每个环境(dev/staging/prod)都有一个存储帐户,则有意义

  • 指定 JobHostConfiguration 类的 HosId 属性:

    var config = new JobHostConfiguration();
    config.HostId = "dev|staging|prod";
    
于 2016-10-28T02:31:19.773 回答
3

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

var config = new JobHostConfiguration();
config.HostId = "dev|prod"
var host = new JobHost(config);
host.RunAndBlock();
于 2016-10-28T01:34:10.487 回答
0

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

于 2016-10-28T01:18:53.433 回答