我们有两个使用TimerTrigger运行的Azure Webjob部署(Prod和Test)。这两个Web应用程序都有单个实例。根据{{3}},TimeTriggers使用单例锁来确保没有并行调用。这两个实例使用相同的存储帐户。我们面临的问题是,只有其中一个部署似乎获得锁定,而其他部署无法获取锁定。如果我们停止第一个webjob,则第二个获取锁定并开始处理,反之亦然。
锁是否依赖于存储帐户?我们如何确保这两个部署都具有单独的锁定机制并同时运行?
答案 0 :(得分:8)
你是对的,你必须使用不同的存储帐户。
在幕后, TimerTrigger 使用WebJobs SDK的 Singleton 功能,确保在任何给定时间只有一个触发函数的实例正在运行。 当JobHost启动时,对于每个TimerTrigger函数,将执行blob租约(Singleton Lock)。此分布式锁定可确保您的计划函数的任何一个实例都可以随时运行。如果当前未租用该功能的blob,则该功能将获取租约并立即开始按计划运行。 如果无法获取blob租约,通常意味着该函数的另一个实例正在运行,因此该函数不会在当前主机中启动。发生这种情况时,主机将继续定期检查是否可以获得租约。这是作为一种"恢复"模式确保在运行稳定状态时,如果实例发生故障,另一个实例通知并在另一个实例停止的地方接收。
如果你看一下锁定机制(StorageScheduleMonitor.cs)的实现:
所以根据@ volodymyr-bilyachat的答案,有两种可能性:
分离存储帐户:如果每个环境都有一个存储帐户(dev / staging / prod),这是有意义的
指定JobHostConfiguration类的HosId属性:
var config = new JobHostConfiguration();
config.HostId = "dev|staging|prod";
答案 1 :(得分:2)
使用不同的存储帐户或设置主机
var config = new JobHostConfiguration();
config.HostId = "dev|prod"
var host = new JobHost(config);
host.RunAndBlock();
答案 2 :(得分:0)
如果使用TimerTrigger,请确保在Web App上启用了Always On。