可配置的计时器触发器 - Azure Web 作业

Posted

技术标签:

【中文标题】可配置的计时器触发器 - Azure Web 作业【英文标题】:Configurable Timer Triggers - Azure Web Jobs 【发布时间】:2018-02-06 10:22:24 【问题描述】:

我正在构建一个定期触发的作业(比如 1 分钟)。我已经成功地使用了在函数中硬编码了时间跨度的触发网络作业。

public void foo([TimerTrigger("00:01:00")] TimerInfo timer)

现在,如果我想将触发时间从 1 分钟更改为 2 分钟,我必须重新部署代码。相反,有一种方法可以通过配置文件使 TimeTrigger 可配置。

请注意,无法用动态读取的值替换字符串,因为 TimerTrigger 属性是 const 字符串表达式或类型。

【问题讨论】:

【参考方案1】:

你可以这样做:

public static void Run([TimerTrigger("%MYSCHEDULE%")] TimerInfo myTimer, ILogger log)

其中MYSCHEDULE 是一个环境变量,您可以将其存储在local.settings.json 文件以及门户中的应用程序设置中。

MYSCHEDULE 的示例值为:

"MYSCHEDULE": "0 */2 * * * *"

【讨论】:

【参考方案2】:

经过大量挖掘,我意识到这可以通过 SDK 扩展类 TimerSchedule 来完成。

为此,您需要一个可用于多个触发器的基类。

class CustomTimerTriggerBase: TimerSchedule

    TimeSpan timer;
    public CustomTimerTriggerBase(string triggerConfigKey)
    
        timer=TimeSpan.Parse(ConfigurationManager.AppSettings[triggerConfigKey]);
    

    public override DateTime GetNextOccurrence(DateTime now)
    
        return now.Add(timer);
    

使用这个 Base 来生成你的计时器...

public sealed class FooTimer : CustomTimerTriggerBase

    public FooTimer() : base("FooTimerKey") 

在您的 App.config 中有一个“FooTimer”的键

<add key="FooTimerKey" value="00:02:00" />

在你的 webjob 函数中使用这个 FooTimer 类。

public void foo([TimerTrigger(typeof(FooTimer)] TimerInfo timer)

现在您可以简单地更改应用配置中的值,而无需重新部署代码。 注意:由于您使用 Timespan 进行解析,因此字符串可以是您需要的任何格式,如 TimeSpan 格式中定义的那样。


更新

正如 l--''''''---------'''''''''''' 和 Andy Dobedoe 现在(截至 2019 年)所指出的,实现这一点要简单得多。

public static async Task RunAsync([TimerTrigger("%MYCRON%")]TimerInfo myTimer

找到名为 MYCRON 的设置并从那里使用 cron 表达式

【讨论】:

这不再有效。如果你在一个函数上加上一个FunctionName 属性(需要它工作)和一个TimerTrigger,它采用type 而不是cron 表达式,它无法在“System.NotImplementedException:Property 'ScheduleType' on Azure Functions 不支持属性“TimerTriggerAttribute”。”【参考方案3】:

事实证明,现在这很容易。只需将应用程序设置作为您的 cron 计划表达式,它就会为您查找。

例如

public static async Task RunAsync([TimerTrigger("%MYCRON%")]TimerInfo myTimer

找到名为 MYCRON 的设置并从那里使用 cron 表达式

【讨论】:

【参考方案4】:

AFAIK,您需要在您的代码中为TimerTrigger 指定scheduleExpression 参数,或者在此示例TimerSamples.cs 中实现您的WeeklyScheduleDailySchedule。为了在不重新部署代码的情况下更改计划,我假设您可以利用Azure Scheduler 在某个计划上触发您的网络作业,并且您可以按照您的预期更改计划设置,而无需重新部署您的网络作业。更多细节可以参考tutorial中关于添加调度作业的部分。

【讨论】:

感谢您的回答。我一直在寻找一种更可配置的方式,而不仅仅是每周或每天的日程安排。我想出了一种使用内置 Azure SDK 的 TimerSchedule 扩展的方法。和WeeklySceduleDailySchedule基本一样,控制力更强。

以上是关于可配置的计时器触发器 - Azure Web 作业的主要内容,如果未能解决你的问题,请参考以下文章

Azure Function App:Http 触发器与计时器触发器

使用Azure Web作业配置应用程序洞察

Azure函数计时器触发器失败运行存储过程的执行[重复]

当我执行代码+测试时,Azure 函数中的计时器触发器不起作用

CRON 表达式在每个月的最后一天触发 Azure 函数

如何在Azure Web作业中的调用范围绑定中配置Ninject?