您现在访问的是微软AZURE全球版技术文档网站,若需要访问由世纪互联运营的MICROSOFT AZURE中国区技术文档网站,请访问 https://docs.azure.cn.

Azure Functions 的计时器触发器Timer trigger for Azure Functions

本文介绍如何在 Azure Functions 中使用计时器触发器。This article explains how to work with timer triggers in Azure Functions. 计时器触发器可以按计划运行函数。A timer trigger lets you run a function on a schedule.

此参考信息面向 Azure Functions 开发人员。This is reference information for Azure Functions developers. Azure Functions 的新手请从以下资源入手:If you're new to Azure Functions, start with the following resources:

包 - Functions 1.xPackages - Functions 1.x

Microsoft.Azure.WebJobs.Extensions NuGet 包 2.x 版中提供了计时器触发器。The timer trigger is provided in the Microsoft.Azure.WebJobs.Extensions NuGet package, version 2.x. azure-webjobs-sdk-extensions GitHub 存储库中提供了此包的源代码。Source code for the package is in the azure-webjobs-sdk-extensions GitHub repository.

在所有开发环境中自动提供对该绑定的支持。Support for this binding is automatically provided in all development environments. 无需手动安装包或注册扩展。You don't have to manually install the package or register the extension.

包 - Functions 2.xPackages - Functions 2.x

Microsoft.Azure.WebJobs.Extensions NuGet 包 3.x 版中提供了计时器触发器。The timer trigger is provided in the Microsoft.Azure.WebJobs.Extensions NuGet package, version 3.x. azure-webjobs-sdk-extensions GitHub 存储库中提供了此包的源代码。Source code for the package is in the azure-webjobs-sdk-extensions GitHub repository.

在所有开发环境中自动提供对该绑定的支持。Support for this binding is automatically provided in all development environments. 无需手动安装包或注册扩展。You don't have to manually install the package or register the extension.

示例Example

参阅语言特定的示例:See the language-specific example:

C# 示例C# example

以下示例显示了一个 C# 函数,每当分钟的值可被 5 整除时,就执行该函数(例如,如果函数起始于 18:57:00,则下一次执行函数的时间为 19:00:00)。The following example shows a C# function that is executed each time the minutes have a value divisible by five (eg if the function starts at 18:57:00, the next performance will be at 19:00:00). TimerInfo 对象将传递到函数中。The TimerInfo object is passed into the function.

[FunctionName("TimerTriggerCSharp")]
public static void Run([TimerTrigger("0 */5 * * * *")]TimerInfo myTimer, ILogger log)
{
    if (myTimer.IsPastDue)
    {
        log.LogInformation("Timer is running late!");
    }
    log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
}

C# 脚本示例C# script example

以下示例演示 function.json 文件中的一个计时器触发器绑定以及使用该绑定的 C# 脚本函数The following example shows a timer trigger binding in a function.json file and a C# script function that uses the binding. 该函数将写入日志信息,指示调用此函数是由于错过了计划发生时间。The function writes a log indicating whether this function invocation is due to a missed schedule occurrence. TimerInfo 对象将传递到函数中。The TimerInfo object is passed into the function.

下面是 function.json 文件中的绑定数据:Here's the binding data in the function.json file:

{
    "schedule": "0 */5 * * * *",
    "name": "myTimer",
    "type": "timerTrigger",
    "direction": "in"
}

C# 脚本代码如下所示:Here's the C# script code:

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}" );  
}

F# 示例F# example

以下示例演示了 function.json 文件中的一个计时器触发器绑定以及使用该绑定的 F# 脚本函数The following example shows a timer trigger binding in a function.json file and an F# script function that uses the binding. 该函数将写入日志信息,指示调用此函数是由于错过了计划发生时间。The function writes a log indicating whether this function invocation is due to a missed schedule occurrence. TimerInfo 对象将传递到函数中。The TimerInfo object is passed into the function.

下面是 function.json 文件中的绑定数据:Here's the binding data in the function.json file:

{
    "schedule": "0 */5 * * * *",
    "name": "myTimer",
    "type": "timerTrigger",
    "direction": "in"
}

F# 脚本代码如下所示:Here's the F# script code:

let Run(myTimer: TimerInfo, log: ILogger ) =
    if (myTimer.IsPastDue) then
        log.LogInformation("F# function is running late.")
    let now = DateTime.Now.ToLongTimeString()
    log.LogInformation(sprintf "F# function executed at %s!" now)

JavaScript 示例JavaScript example

以下示例演示 function.json 文件中的一个计时器触发器绑定以及使用该绑定的 JavaScript 函数The following example shows a timer trigger binding in a function.json file and a JavaScript function that uses the binding. 该函数将写入日志信息,指示调用此函数是由于错过了计划发生时间。The function writes a log indicating whether this function invocation is due to a missed schedule occurrence. 计时器对象将传递到函数中。A timer object is passed into the function.

下面是 function.json 文件中的绑定数据:Here's the binding data in the function.json file:

{
    "schedule": "0 */5 * * * *",
    "name": "myTimer",
    "type": "timerTrigger",
    "direction": "in"
}

JavaScript 代码如下所示:Here's the JavaScript code:

module.exports = function (context, myTimer) {
    var timeStamp = new Date().toISOString();

    if (myTimer.IsPastDue)
    {
        context.log('Node is running late!');
    }
    context.log('Node timer trigger function ran!', timeStamp);   

    context.done();
};

Java 示例Java example

以下示例函数的触发和执行间隔为 5 分钟。The following example function triggers and executes every five minutes. 函数上的 @TimerTrigger 注释使用与 CRON 表达式相同的字符串格式定义计划。The @TimerTrigger annotation on the function defines the schedule using the same string format as CRON expressions.

@FunctionName("keepAlive")
public void keepAlive(
  @TimerTrigger(name = "keepAliveTrigger", schedule = "0 */5 * * * *") String timerInfo,
      ExecutionContext context
 ) {
     // timeInfo is a JSON string, you can deserialize it to an object using your favorite JSON library
     context.getLogger().info("Timer is triggered: " + timerInfo);
}

属性Attributes

C# 类库中,使用 TimerTriggerAttributeIn C# class libraries, use the TimerTriggerAttribute.

该特性的构造函数采用 CRON 表达式或 TimeSpanThe attribute's constructor takes a CRON expression or a TimeSpan. 仅当函数应用在应用服务计划中运行时才能使用 TimeSpanYou can use TimeSpan only if the function app is running on an App Service plan. 以下示例显示了一个 CRON 表达式:The following example shows a CRON expression:

[FunctionName("TimerTriggerCSharp")]
public static void Run([TimerTrigger("0 */5 * * * *")]TimerInfo myTimer, ILogger log)
{
    if (myTimer.IsPastDue)
    {
        log.LogInformation("Timer is running late!");
    }
    log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
}

配置Configuration

下表解释了在 function.json 文件和 TimerTrigger 特性中设置的绑定配置属性。The following table explains the binding configuration properties that you set in the function.json file and the TimerTrigger attribute.

function.json 属性function.json property Attribute 属性Attribute property 说明Description
typetype 不适用n/a 必须设置为“timerTrigger”。Must be set to "timerTrigger". 在 Azure 门户中创建触发器时,会自动设置此属性。This property is set automatically when you create the trigger in the Azure portal.
directiondirection 不适用n/a 必须设置为“in”。Must be set to "in". 在 Azure 门户中创建触发器时,会自动设置此属性。This property is set automatically when you create the trigger in the Azure portal.
namename 不适用n/a 在函数代码中表示计时器对象的变量的名称。The name of the variable that represents the timer object in function code.
scheduleschedule ScheduleExpressionScheduleExpression CRON 表达式TimeSpan 值。A CRON expression or a TimeSpan value. 只能对在应用服务计划中运行的函数应用使用 TimeSpanA TimeSpan can be used only for a function app that runs on an App Service Plan. 可以将计划表达式放在应用设置中并将此属性设置为用 % 符号括起的应用设置名称,例如此示例中的“%ScheduleAppSetting%”。You can put the schedule expression in an app setting and set this property to the app setting name wrapped in % signs, as in this example: "%ScheduleAppSetting%".
runOnStartuprunOnStartup RunOnStartupRunOnStartup 如果为 true,则在运行时启动时调用此函数。If true, the function is invoked when the runtime starts. 例如,当函数应用从由于无活动而进入的空闲状态醒来后,运行时会启动。For example, the runtime starts when the function app wakes up after going idle due to inactivity. 当函数应用由于函数更改而重新启动时,以及当函数应用横向扩展时。因此 runOnStartup 应很少设置为 true(如果曾经设置过),尤其是在生产中。when the function app restarts due to function changes, and when the function app scales out. So runOnStartup should rarely if ever be set to true, especially in production.
useMonitoruseMonitor UseMonitorUseMonitor 设置为 truefalse 以指示是否应当监视计划。Set to true or false to indicate whether the schedule should be monitored. 计划监视在各次计划发生后会持续存在,以帮助确保即使在函数应用实例重新启动的情况下也能正确维护计划。Schedule monitoring persists schedule occurrences to aid in ensuring the schedule is maintained correctly even when function app instances restart. 如果未显式设置,则对于重复周期间隔大于 1 分钟的计划,默认值为 trueIf not set explicitly, the default is true for schedules that have a recurrence interval greater than 1 minute. 对于每分钟触发多次的计划,默认值为 falseFor schedules that trigger more than once per minute, the default is false.

在本地进行开发时,应用设置将取 local.settings.json 文件的值。When you're developing locally, app settings go into the local.settings.json file.

注意

在生产中不建议将 runOnStartup 设置为 trueWe recommend against setting runOnStartup to true in production. 使用此设置会使代码在非常不可预测的时间执行。Using this setting makes code execute at highly unpredictable times. 在某些生产设置中,这些额外执行可能会导致消耗计划中托管的应用产生明显更高的成本。In certain production settings, these extra executions can result in significantly higher costs for apps hosted in Consumption plans. 例如,对于runOnStartup启用横向扩展函数应用,将调用该触发器。For example, with runOnStartup enabled the trigger is invoked whenever your function app is scaled. 在生产中启用 runOnStartup 之前,请确保完全了解函数的生产行为。Make sure you fully understand the production behavior of your functions before enabling runOnStartup in production.

使用情况Usage

调用计时器触发器函数时,计时器对象将传递到函数中。When a timer trigger function is invoked, a timer object is passed into the function. 以下 JSON 是计时器对象的示例表示形式。The following JSON is an example representation of the timer object.

{
    "Schedule":{
    },
    "ScheduleStatus": {
        "Last":"2016-10-04T10:15:00+00:00",
        "LastUpdated":"2016-10-04T10:16:00+00:00",
        "Next":"2016-10-04T10:20:00+00:00"
    },
    "IsPastDue":false
}

如果当前函数调用晚于计划时间,则 IsPastDue 属性为 trueThe IsPastDue property is true when the current function invocation is later than scheduled. 例如,函数应用重新启动可能会导致调用被错过。For example, a function app restart might cause an invocation to be missed.

CRON 表达式CRON expressions

Azure Functions 使用 NCronTab 库来解释 CRON 表达式。Azure Functions uses the NCronTab library to interpret CRON expressions. CRON 表达式包含六个字段:A CRON expression includes six fields:

{second} {minute} {hour} {day} {month} {day-of-week}

每个字段可以具有下列类型之一的值:Each field can have one of the following types of values:

TypeType 示例Example 何时触发When triggered
一个具体值A specific value "0 5 * * * *""0 5 * * * *" 在 hh:05:00,其中 hh 表示每小时(每小时一次)at hh:05:00 where hh is every hour (once an hour)
所有值 (*)All values (*) "0 * 5 * * *""0 * 5 * * *" 在每天的 5:mm:00,其中 mm 表示该小时的每分钟(一天 60 次)at 5:mm:00 every day, where mm is every minute of the hour (60 times a day)
一个范围(- 运算符)A range (- operator) "5-7 * * * * *""5-7 * * * * *" 在 hh:mm:05、hh:mm:06 和 hh:mm:07,其中 hh:mm 表示每小时的每分钟(每分钟 3 次)at hh:mm:05,hh:mm:06, and hh:mm:07 where hh:mm is every minute of every hour (3 times a minute)
一组值(, 运算符)A set of values (, operator) "5,8,10 * * * * *""5,8,10 * * * * *" 在 hh:mm:05、hh:mm:08 和 hh:mm:10,其中 hh:mm 表示每小时的每分钟(每分钟 3 次)at hh:mm:05,hh:mm:08, and hh:mm:10 where hh:mm is every minute of every hour (3 times a minute)
一个间隔值(/ 运算符)An interval value (/ operator) "0 */5 * * * *""0 */5 * * * *" 在 hh:05:00、hh:10:00、hh:15:00,依此类推,直到 hh:55:00,其中 hh 表示每小时(每小时 12 次)at hh:05:00, hh:10:00, hh:15:00, and so on through hh:55:00 where hh is every hour (12 times an hour)

若要指定月份或天,可以使用数字值、名称或名称的缩写:To specify months or days you can use numeric values, names, or abbreviations of names:

  • 对于天,数字值为 0 到 6,其中 0 表示星期日。For days, the numeric values are 0 to 6 where 0 starts with Sunday.
  • 名称采用英语。Names are in English. 例如:MondayJanuaryFor example: Monday, January.
  • 名称不区分大小写。Names are case-insensitive.
  • 名称可缩写。Names can be abbreviated. 三字母是建议的缩写长度。Three letters is the recommended abbreviation length. 例如:MonJanFor example: Mon, Jan.

CRON 示例CRON examples

以下是一些可用于 Azure Functions 中计时器触发器的 CRON 表达式示例。Here are some examples of CRON expressions you can use for the timer trigger in Azure Functions.

示例Example 何时触发When triggered
"0 */5 * * * *" 每五分钟一次once every five minutes
"0 0 * * * *" 每小时一次(在每小时的开头)once at the top of every hour
"0 0 */2 * * *" 每两小时一次once every two hours
"0 0 9-17 * * *" 从上午 9 点到下午 5 点每小时一次once every hour from 9 AM to 5 PM
"0 30 9 * * *" 每天上午 9:30at 9:30 AM every day
"0 30 9 * * 1-5" 每个工作日的上午 9:30at 9:30 AM every weekday
"0 30 9 * Jan Mon" 在一月份每星期一的上午 9:30at 9:30 AM every Monday in January

备注

你可以在线找到 CRON 表达式示例,但它们中的许多都省略了 {second} 字段。You can find CRON expression examples online, but many of them omit the {second} field. 如果从这些字段之一复制,请添加缺少的 {second} 字段。If you copy from one of them, add the missing {second} field. 通常,你希望该字段的值为零,而不是星号。Usually you'll want a zero in that field, not an asterisk.

CRON 时区CRON time zones

CRON 表达式中的数字指的是时间和日期,而不是时间跨度。The numbers in a CRON expression refer to a time and date, not a time span. 例如,hour 字段中的 5 指的是 5:00 AM,而不是每 5 小时。For example, a 5 in the hour field refers to 5:00 AM, not every 5 hours.

CRON 表达式使用的默认时区为协调世界时 (UTC)。The default time zone used with the CRON expressions is Coordinated Universal Time (UTC). 若要让 CRON 表达式基于其他时区,请为你的函数应用创建一个名为 WEBSITE_TIME_ZONE 的应用设置。To have your CRON expression based on another time zone, create an app setting for your function app named WEBSITE_TIME_ZONE. 将值设置为所需时区的名称,如 Microsoft 时区索引中所示。Set the value to the name of the desired time zone as shown in the Microsoft Time Zone Index.

例如,东部标准时间是 UTC-05:00。For example, Eastern Standard Time is UTC-05:00. 若要让计时器触发器每天在美国东部时间上午 10:00 触发,可使用表示 UTC 时区的以下 CRON 表达式:To have your timer trigger fire at 10:00 AM EST every day, use the following CRON expression that accounts for UTC time zone:

"schedule": "0 0 15 * * *"

或者为你的函数应用创建一个名为 WEBSITE_TIME_ZONE 的应用设置并将值设置为 Eastern Standard TimeOr create an app setting for your function app named WEBSITE_TIME_ZONE and set the value to Eastern Standard Time. 然后使用以下 CRON 表达式:Then uses the following CRON expression:

"schedule": "0 0 10 * * *"

当使用 WEBSITE_TIME_ZONE,时间将针对特定时区中的时间更改进行调整,例如夏令时。When you use WEBSITE_TIME_ZONE, the time is adjusted for time changes in the specific timezone, such as daylight savings time.

TimeSpanTimeSpan

只能对在应用服务计划中运行的函数应用使用 TimeSpanA TimeSpan can be used only for a function app that runs on an App Service Plan.

与 CRON 表达式不同,TimeSpan 值指定各次函数调用之间的时间间隔。Unlike a CRON expression, a TimeSpan value specifies the time interval between each function invocation. 如果函数的运行时间超出了指定的时间间隔,则在函数完成时,计时器会立即再次调用该函数。When a function completes after running longer than the specified interval, the timer immediately invokes the function again.

以字符串表示,当 hh 小于 24 时,TimeSpan 格式为 hh:mm:ssExpressed as a string, the TimeSpan format is hh:mm:ss when hh is less than 24. 当前两个数字是 24 或更大的数字时,格式为 dd:hh:mmWhen the first two digits are 24 or greater, the format is dd:hh:mm. 下面是一些可能的恶意活动:Here are some examples:

示例Example 何时触发When triggered
"01:00:00""01:00:00" 每小时every hour
"00:01:00""00:01:00" 每分钟every minute
"24:00:00""24:00:00" 每天everyday

横向扩展Scale-out

如果函数应用横向扩展到多个实例,则在所有实例中只会运行由计时器触发的函数的单个实例。If a function app scales out to multiple instances, only a single instance of a timer-triggered function is run across all instances.

共享同一存储的函数应用Function apps sharing Storage

如果在多个函数应用之间共享存储帐户,请确保每个函数应用在 host.json 中都有不同的 idIf you share a Storage account across multiple function apps, make sure that each function app has a different id in host.json. 可以省略 id 属性或手动将每个函数应用的 id 设置为不同的值。You can omit the id property or manually set each function app's id to a different value. 计时器触发器使用存储锁来确保当函数应用横向扩展到多个实例时将只有一个计时器实例。The timer trigger uses a storage lock to ensure that there will be only one timer instance when a function app scales out to multiple instances. 如果两个函数应用共享相同的 id 且每个都使用计时器触发器,则只会运行一个计时器。If two function apps share the same id and each uses a timer trigger, only one timer will run.

重试行为Retry behavior

与队列触发器不同,计时器触发器在函数失败后不会重试。Unlike the queue trigger, the timer trigger doesn't retry after a function fails. 函数失败时,在计划的下次时间到来前,不会再次调用该函数。When a function fails, it isn't called again until the next time on the schedule.

故障排除Troubleshooting

有关在计时器触发器未按预期工作的情况下应采取的措施,请参阅调查和报告有关计时器触发功能未触发的问题For information about what to do when the timer trigger doesn't work as expected, see Investigating and reporting issues with timer triggered functions not firing.

后续步骤Next steps