如何配置Azure Webjob Timer Trigger不以单例模式运行?
解决方案
首先明确结论:可以实现每个WebJob实例独立执行Timer触发的预配作业,不需要走默认的单例模式。
默认Azure WebJobs SDK的TimerTrigger绑定了单例锁逻辑,靠Storage Account的Blob租约实现,同一时间只有一个实例能拿到锁执行作业,就是你目前遇到的情况。要关掉这个行为,直接在TimerTrigger的属性配置里修改即可:
- 如果你用的是WebJobs SDK 3.x及以上版本,给TimerTrigger显式指定
UseMonitor = false即可,示例代码:
public static void SyncSubscriptionWorker([TimerTrigger("0 */5 * * * *", UseMonitor = false)] TimerInfo timer) { // 你的同步预配逻辑 }
UseMonitor设为false后,SDK不会再申请全局的Blob租约锁,每个扩展出来的WebJob实例都会按你设定的Cron表达式独立执行这个Timer作业,不会互相影响。
- 如果是更低版本的WebJobs SDK,没有
UseMonitor参数的话,可以直接在程序启动时全局关掉Timer的单例模式,配置代码:
var config = new JobHostConfiguration(); config.UseTimers(new TimersConfiguration { UseMonitor = false }); var host = new JobHost(config); host.RunAndBlock();
额外注意事项
- 关掉全局锁之后,你的同步预配逻辑要做好幂等处理,同一个实例重复执行、多个实例同时执行的时候,不要重复创建工作器,也不要出现冲突报错。
- 你可以在每个实例本地维护一个已监听的Subscription列表,同步的时候对比全局的Subscription列表,只给当前实例新增还没监听的Subscription的工作器,就能保证每个扩展出来的实例都能监听对应Subscription,充分发挥横向扩展的能力。
- 同步间隔不要设置太密,避免不必要的资源开销,一般5到15分钟的同步间隔对于大部分场景都足够了。
内容的提问来源于stack exchange,提问作者Zach Johnson
相关产品推荐
相关产品推荐

