通过应用程序设置配置Azure Function计时器

62

我正在研究Azure函数计时器作业,需要从appsettings中获取cron表达式。请告诉我,在Azure函数中如何从appsettings获取值。我想让我的Azure函数从上午9:00到下午12:00每30分钟运行一次。

{
 "disabled": false,
 "bindings": [
   {
     "name": "timerInfo",
     "type": "timerTrigger",
     "direction": "in",
     "schedule": "0 * * * * *"
   }
 ]
}

1
你尝试过什么?它使用cron语法,也许可以从那里开始(https://crontab-generator.org/)。 - Mark
6个回答

94

将计划设置为"schedule": "%EmailScheduleTriggerTime%",然后在appsetting.json或local.settings.json中设置EmailScheduleTriggerTime的值为"0 30 9-12 * * *"

{
  "IsEncrypted": false,
  "Values": {
    "EmailScheduleTriggerTime": "0 30 9-12 * * *", //Run every  30 minutes from 9:00 to 12:00

  },
  "ConnectionStrings": {
    "DefaultConnection": ""
  }
}

[FunctionName("TimerfunctionApp")] 
public static void Run([TimerTrigger("%EmailScheduleTriggerTime%")] TimerInfo TInfo, TraceWriter log)

1
你能指给我官方文档吗?我在那里找不到这个。 - jayasurya_j
1
这是你所要求的吗?https://learn.microsoft.com/zh-cn/azure/azure-functions/functions-bindings-timer#cron-expressions - Karthikeyan VK
我指的是你在文档中找到哪里提到了%variable%将被替换为环境变量“variable”。 - jayasurya_j
2
这是链接:https://learn.microsoft.com/zh-cn/azure/azure-functions/functions-triggers-bindings#binding-expressions---app-settings - Benny Bauer
13
有人在本地成功运行过吗?当我在local.settings.json中指定一个设置时,会出现错误:“Microsoft.Azure.WebJobs.Host: Error indexing method 'MainTriggerEntry'. Microsoft.Azure.WebJobs.Host: '%CRON_EXPRESSION%' does not resolve to a value.” - Denis Molodtsov
显示剩余8条评论

48

如果您正在使用VS2017函数工具,并在.NET项目中定义函数(而不是直接在Azure门户中定义),则可以使用%语法从AppSettings获取间隔:

[FunctionName("MyTimerFunction")] 
public static void Run([TimerTrigger("%TimerInterval%")] TimerInfo myTimer, TraceWriter log, ..

然后在您的应用程序设置中指定所需的CRON格式间隔,例如在local.settings.json中。

{
  "Values" : { 
      "TimerInterval" : "0 30 9-12 * * *"
    }
}

1
为什么会有踩票?如果有反馈,我很乐意改进这个答案。 - Garth Mason
你的回答只是问题的一部分,使用0 30 9-12 * * *,我已经编辑并发送了评论。 - Karthikeyan VK
很不幸,当您将函数部署到Azure时,它无法正常工作。“错误索引方法'SampleFunction.Run' '%TimerInterval%'未解析为值。”local.settings.json与函数一起部署。 - Viktors Telle
1
解决方法是在Azure门户中的Azure函数应用程序设置中设置“TimerInterval”值,但我希望在部署期间可以配置此值。 - Viktors Telle
1
在这里找到了解决方案:https://octopus.com/blog/azure-functions#step-2-update-appsettings - Viktors Telle
显示剩余2条评论

31

除了从 Values 配置对象中获取值之外,您还可以使用 % 语法从配置文件 (appsettings.json) 文件中获取任何字段的任何值。

例如:

appsettings.json:

{      
  "ScheduleConfiguration": {
    "FunctionOne": {
      "CronExpression": "0 40 2 * * *"
    }
  }
}

Functions.cs:

    /// <summary>
    /// %ScheduleConfiguration:FunctionOne:CronExpression%
    ///  - e.g. "0 40 2 * * *" - executes at 02:40:00am every day
    /// </summary>
    [FunctionName("FunctionOne")]
    public async Task FunctionOne(
        [TimerTrigger("%ScheduleConfiguration:FunctionOne:CronExpression%")]
        TimerInfo timerInfo)
    {
        // Azure function code
    }

2
根据 https://dev59.com/p1kR5IYBdhLWcg3w1wch#45680677 的说法,appsettings.json 已被重命名为 local.settings.json,以使其更清晰地表明它仅适用于本地开发 - Tim Abell
2
如果你想要部署到 Linux 上,使用双下划线 '__' 而不是 ':'。Windows 两种都可以理解。 - Pieter
不幸的是,即使我将它明确添加到.NET配置构建器.AddJsonFile("appsettings.json")中,它也无法与appsettings.json一起工作。我经常有很多其他逻辑设置,我也想将其提供给生产环境,所以我使用默认值包含此文件,就像我为Web API做的那样。但是似乎函数不会从.NET配置加载其参数值,因此只有环境变量会起作用。是否有其他方法可以在配置文件中获取此时间触发器值并且不需要显式环境设置? - JustAMartin

6

由于这篇文章已经有了很好的答案,我想在这里分享我的经验。 我尝试通过将cron表达式添加到 appsettings.json 文件中来在本地运行应用程序,但是当我运行函数应用程序时,我总是收到以下错误:

'EmployeeTimerTrigger'函数出错: Microsoft.Azure.WebJobs.Host:索引方法时出错'EmployeeTimerTrigger'. Microsoft.Azure.WebJobs.Host:'%EmployeeTimerTrigger%'无法解析为值。

所以为了解决这个问题,我们需要将cron表达式从 appsettings.json 移动到 local.settings.json ,然后它可以正常工作,我能够在本地测试它。

编辑:添加部署说明

函数应用程序从Azure函数应用程序自身的应用程序设置中读取定时器触发器设置。

当您计划在Azure中部署函数应用程序时,您需要对Azure门户中的函数应用程序的应用程序设置进行一些小修改。

您可以通过选择Azure门户中的函数应用程序 ->配置 ->应用程序设置来导航到这些设置。

您需要添加的第一个设置是您希望计时器触发器在其中运行的时区,这是相同示例:

注意:请注意这些值区分大小写

Key = WEBSITE_TIME_ZONE

现在我们将在此处添加的第二个设置是用于我们的计时器触发功能,这张图片中您将看到计时器将在东部标准时间早上10:00 AM和下午2:00运行。

为什么使用东部标准时间? 好吧,记得我们的第一个设置是网站时区,因此两个设置相互配合工作。

注意:计时器触发器的名称应该与您的函数应用程序中一致,请注意这些值区分大小写,并且应该与您的计时器触发器函数中的完全匹配。

enter image description here

完成这些设置后,请不要忘记保存更改,现在您已准备好部署函数应用程序了。

我希望这个答案有助于部署和在本地运行计时器函数。


您提出的更改意味着该值在生产中未被使用(如果我有限的理解是正确的)。 - Tim Abell
你好@TimAbell,我已经在我的答案中添加了部署步骤,请查看并告诉我是否有所帮助。如果有帮助,请给我点赞 :) - NSDumb
1
是的,我认为这澄清了事情,谢谢。 - Tim Abell
是的,即使我明确将其添加到.NET配置生成器.AddJsonFile("appsettings.json")中,它也无法与appsettings.json一起使用。我经常有很多其他逻辑设置要传递到生产环境,因此我会像为Web API一样包含此文件以获取默认值。但似乎函数不会从.NET配置加载其参数值,因此只有环境变量才能起作用。是否有其他方法可以在配置文件中获取此时间触发器值而不是显式环境设置? - JustAMartin
还有一件重要的事情:如果您的cron表达式名称包含__(因为我们经常需要支持Linux和Windows),那么不要忘记在触发器函数定义中用:替换__。例如,在Web应用程序配置(以及local.settings.json值)中的My__Cron__Timer应该在您的函数中被称为My:Cron:Timer - JustAMartin

1

-1
请参考以下 Microsoft 文档: Azure Functions 的计时器触发器 示例 Json 配置:
{
    "schedule": "0 */5 * * * *",
    "name": "myTimer",
    "type": "timerTrigger",
    "direction": "in"
}

C# 代码:

public static void Run(TimerInfo myTimer, ILogger log)
{
    if (myTimer.IsPastDue)
    {
        log.LogInformation("Timer is running late!");
    }
    log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}" );  
}

代码来源:微软网站


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