你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
本文介绍如何在 Azure Functions 中使用计时器触发器。 计时器触发器可以按计划运行函数。
此参考信息面向 Azure Functions 开发人员。 Azure Functions 的新手请从以下资源入手:
若要了解如何手动运行计时器触发的函数,请参阅手动运行非 HTTP 触发的函数。
在所有开发环境中自动提供对该绑定的支持。 无需手动安装包或注册扩展。
Source code for the timer extension package is in the azure-webjobs-sdk-extensions GitHub repository.
Important
本文使用选项卡来支持多个版本的 Node.js 编程模型。 v4 模型已正式发布,旨在为 JavaScript 和 TypeScript 开发人员提供更为灵活和直观的体验。 有关 v4 模型工作原理的更多详细信息,请参阅 Azure Functions Node.js 开发人员指南。 To learn more about the differences between v3 and v4, refer to the migration guide.
Azure Functions 支持两种 Python 编程模型。 定义绑定的方式取决于选择的编程模型。
使用 Python v2 编程模型,可以直接在 Python 函数代码中使用修饰器定义绑定。 有关详细信息,请参阅 Python 开发人员指南。
本文同时支持两个编程模型。
Example
此示例演示一个 C# 函数,每次分钟数为 5 的倍数值时执行该函数。 例如,当函数从 18:55:00 开始时,下一次执行为 19:00:00。
TimerInfo
对象将传递到函数中。
可使用以下 C# 模式之一来创建 C# 函数:
-
独立辅助角色模型:编译的 C# 函数,该函数在独立于运行时的工作进程中运行。 需要独立工作进程才能支持在 LTS 和非 LTS 版 .NET 和 .NET Framework 上运行的 C# 函数。 独立工作进程函数的扩展使用
Microsoft.Azure.Functions.Worker.Extensions.*
命名空间。 -
In-process model: Compiled C# function that runs in the same process as the Functions runtime. In a variation of this model, Functions can be run using C# scripting, which is supported primarily for C# portal editing. 进程内函数的扩展使用
Microsoft.Azure.WebJobs.Extensions.*
命名空间。
Important
对进程内模型的支持将于 2026 年 11 月 10 日结束。 为获得完全支持,强烈建议将应用迁移到独立工作模型。
[Function(nameof(TimerFunction))]
[FixedDelayRetry(5, "00:00:10")]
public static void Run([TimerTrigger("0 */5 * * * *")] TimerInfo timerInfo,
FunctionContext context)
{
var logger = context.GetLogger(nameof(TimerFunction));
logger.LogInformation($"Function Ran. Next timer schedule = {timerInfo.ScheduleStatus?.Next}");
}
以下示例函数的触发和执行间隔为 5 分钟。 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);
}
以下示例显示了计时器触发器绑定和使用绑定的函数代码(其中表示计时器的实例传递给函数)。 该函数将写入日志信息,指示调用此函数是由于错过了计划发生时间。 该示例取决于使用的是 v1 还是 v2 Python 编程模型。
import datetime
import logging
import azure.functions as func
app = func.FunctionApp()
@app.function_name(name="mytimer")
@app.timer_trigger(schedule="0 */5 * * * *",
arg_name="mytimer",
run_on_startup=False)
def test_function(mytimer: func.TimerRequest) -> None:
utc_timestamp = datetime.datetime.utcnow().replace(
tzinfo=datetime.timezone.utc).isoformat()
if mytimer.past_due:
logging.info('The timer is past due!')
logging.info('Python timer trigger function ran at %s', utc_timestamp)
The following example shows a timer trigger TypeScript function.
import { app, InvocationContext, Timer } from '@azure/functions';
export async function timerTrigger1(myTimer: Timer, context: InvocationContext): Promise<void> {
context.log('Timer function processed request.');
}
app.timer('timerTrigger1', {
schedule: '0 */5 * * * *',
handler: timerTrigger1,
});
The following example shows a timer trigger JavaScript function.
Here's the binding data in the function.json file:
{
"schedule": "0 */5 * * * *",
"name": "myTimer",
"type": "timerTrigger",
"direction": "in"
}
下面是 run.ps1 文件中的计时器函数代码:
# Input bindings are passed in via param block.
param($myTimer)
# Get the current universal time in the default string format.
$currentUTCtime = (Get-Date).ToUniversalTime()
# The 'IsPastDue' property is 'true' when the current function invocation is later than scheduled.
if ($myTimer.IsPastDue) {
Write-Host "PowerShell timer is running late!"
}
# Write an information log with the current time.
Write-Host "PowerShell timer trigger function ran! TIME: $currentUTCtime"
Attributes
In-process C# library uses TimerTriggerAttribute from Microsoft.Azure.WebJobs.Extensions whereas isolated worker process C# library uses TimerTriggerAttribute from Microsoft.Azure.Functions.Worker.Extensions.Timer to define the function. C# 脚本改为使用 function.json 配置文件。
Attribute property | Description |
---|---|
Schedule | A CRON expression or a TimeSpan value. 只能对在应用服务计划中运行的函数应用使用 TimeSpan 。 可以将计划表达式放在应用设置中并将此属性设置为用 % 符号括起的应用设置名称,例如 %ScheduleAppSetting% 。 |
RunOnStartup | 如果为 true ,则在运行时启动时调用此函数。 例如,当函数应用从由于无活动而进入的空闲状态醒来后,运行时会启动。 当函数应用由于函数更改而重新启动时,以及当函数应用横向扩展时。请谨慎使用。RunOnStartup 应该很少设置为 true (如果曾经设置过),特别是在生产中。 |
UseMonitor | 设置为 true 或 false 以指示是否应当监视计划。 计划监视在各次计划发生后会持续存在,以帮助确保即使在函数应用实例重新启动的情况下也能正确维护计划。 如果未显式设置,则对于重复周期间隔大于或等于 1 分钟的计划,默认值为 true 。 对于每分钟触发多次的计划,默认值为 false 。 |
Decorators
仅适用于 Python v2 编程模型。
对于使用修饰器定义的 Python v2 功能,支持 schedule
上的以下属性:
Property | Description |
---|---|
arg_name |
在函数代码中表示计时器对象的变量的名称。 |
schedule |
A NCRONTAB expression or a TimeSpan value. 只能对在应用服务计划中运行的函数应用使用 TimeSpan 。 可以将计划表达式放在应用设置中并将此属性设置为用 % 符号括起的应用设置名称,例如此示例中的“%ScheduleAppSetting%”。 |
run_on_startup |
如果为 true ,则在运行时启动时调用此函数。 例如,当函数应用从由于无活动而进入的空闲状态醒来后,运行时会启动。 当函数应用由于函数更改而重新启动时,以及当函数应用横向扩展时。请谨慎使用。runOnStartup 应该很少设置为 true (如果曾经设置过),特别是在生产中。 |
use_monitor |
设置为 true 或 false 以指示是否应当监视计划。 计划监视在各次计划发生后会持续存在,以帮助确保即使在函数应用实例重新启动的情况下也能正确维护计划。 如果未显式设置,则对于重复周期间隔大于或等于 1 分钟的计划,默认值为 true 。 对于每分钟触发多次的计划,默认值为 false 。 |
For Python functions defined by using function.json, see the Configuration section.
Annotations
The @TimerTrigger
annotation on the function defines the schedule
using the same string format as CRON expressions. 该注释支持以下设置:
Configuration
仅适用于 Python v1 编程模型。
下表说明了可以在传递给 options
方法的 app.timer()
对象上设置的属性。
Property | Description |
---|---|
schedule | A NCRONTAB expression or a TimeSpan value. 只能对在应用服务计划中运行的函数应用使用 TimeSpan 。 可以将计划表达式放在应用设置中并将此属性设置为用 % 符号括起的应用设置名称,例如此示例中的“%ScheduleAppSetting%”。 |
runOnStartup | 如果为 true ,则在运行时启动时调用此函数。 例如,当函数应用从由于无活动而进入的空闲状态醒来后,运行时会启动。 当函数应用由于函数更改而重新启动时,以及当函数应用横向扩展时。请谨慎使用。runOnStartup 应该很少设置为 true (如果曾经设置过),特别是在生产中。 |
useMonitor | 设置为 true 或 false 以指示是否应当监视计划。 计划监视在各次计划发生后会持续存在,以帮助确保即使在函数应用实例重新启动的情况下也能正确维护计划。 如果未显式设置,则对于重复周期间隔大于或等于 1 分钟的计划,默认值为 true 。 对于每分钟触发多次的计划,默认值为 false 。 |
The following table explains the binding configuration properties that you set in the function.json file.
function.json property | Description |
---|---|
type | 必须设置为“timerTrigger”。 在 Azure 门户中创建触发器时,会自动设置此属性。 |
direction | 必须设置为“in”。 在 Azure 门户中创建触发器时,会自动设置此属性。 |
name | 在函数代码中表示计时器对象的变量的名称。 |
schedule | A NCRONTAB expression or a TimeSpan value. 只能对在应用服务计划中运行的函数应用使用 TimeSpan 。 可以将计划表达式放在应用设置中并将此属性设置为用 % 符号括起的应用设置名称,例如此示例中的“%ScheduleAppSetting%”。 |
runOnStartup | 如果为 true ,则在运行时启动时调用此函数。 例如,当函数应用从由于无活动而进入的空闲状态醒来后,运行时会启动。 当函数应用由于函数更改而重新启动时,以及当函数应用横向扩展时。请谨慎使用。runOnStartup 应该很少设置为 true (如果曾经设置过),特别是在生产中。 |
useMonitor | 设置为 true 或 false 以指示是否应当监视计划。 计划监视在各次计划发生后会持续存在,以帮助确保即使在函数应用实例重新启动的情况下也能正确维护计划。 如果未显式设置,则对于重复周期间隔大于或等于 1 分钟的计划,默认值为 true 。 对于每分钟触发多次的计划,默认值为 false 。 |
When you're developing locally, add your application settings in the local.settings.json file in the Values
collection.
Caution
Don't set runOnStartup to true
in production. 使用此设置会使代码在非常不可预测的时间执行。 在某些生产设置中,这些额外执行可能会导致消耗计划中托管的应用产生明显更高的成本。 For example, with runOnStartup enabled the trigger is invoked whenever your function app is scaled. Make sure you fully understand the production behavior of your functions before enabling runOnStartup in production.
See the Example section for complete examples.
Usage
调用计时器触发器函数时,计时器对象将传递到函数中。 以下 JSON 是计时器对象的示例表示形式。
{
"Schedule":{
"AdjustForDST": true
},
"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
}
{
"schedule":{
"adjustForDST": true
},
"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
属性为 true
。 例如,函数应用重新启动可能会导致调用被错过。
NCRONTAB expressions
Azure Functions uses the NCronTab library to interpret NCRONTAB expressions. NCRONTAB 表达式类似于 CRON 表达式,不同之处在于它在开头包含额外的第六个字段,用于以秒为单位的时间精度:
{second} {minute} {hour} {day} {month} {day-of-week}
每个字段可以具有下列类型之一的值:
类型 | Example | When triggered |
---|---|---|
一个具体值 | 0 5 * * * * |
一天中每小时的第 5 分钟 |
所有值 (* ) |
0 * 5 * * * |
在第 5 小时期间,一小时的每一分钟 |
一个范围(- 运算符) |
5-7 * * * * * |
一分钟三次 - 每天每小时的每分钟的第 5 到 7 秒 |
一组值(, 运算符) |
5,8,10 * * * * * |
一分钟三次 - 每天每小时的每分钟的第 5、8 和 10 秒 |
一个间隔值(/ 运算符) |
0 */5 * * * * |
一小时 12 次 - 每天每小时的每 5分钟的第 0 秒 |
若要指定月份或天,可以使用数字值、名称或名称的缩写:
- 对于天,数字值为 0 到 6,其中 0 表示星期日。
- 名称采用英语。 例如:
Monday
、January
。 - 名称不区分大小写。
- 名称可缩写。 建议对缩写使用三个字母。 例如:
Mon
、Jan
。
NCRONTAB examples
以下是一些可用于 Azure Functions 中计时器触发器的 NCRONTAB 表达式示例。
Example | When triggered |
---|---|
0 */5 * * * * |
每五分钟一次 |
0 0 * * * * |
每小时一次(在每小时的开头) |
0 0 */2 * * * |
每两小时一次 |
0 0 9-17 * * * |
从上午 9 点到下午 5 点每小时一次 |
0 30 9 * * * |
每天上午 9:30 |
0 30 9 * * 1-5 |
每个工作日的上午 9:30 |
0 30 9 * Jan Mon |
在一月份每星期一的上午 9:30 |
Note
NCRONTAB expression supports both five field and six field format. 第六个字段的位置是秒的值,该值置于表达式的开头。 如果 CRON 表达式无效,则 Azure 门户函数测试将显示 404 错误,如果已连接 Application Insights,则会在那里记录更多详细信息。
NCRONTAB 时区
NCRONTAB 表达式中的数字指的是时间和日期,而不是时间跨度。 例如,hour
字段中的 5 指的是 5:00 AM,而不是每 5 小时。
CRON 表达式使用的默认时区为协调世界时 (UTC)。 若要让 CRON 表达式基于其他时区,请为你的函数应用创建一个名为 WEBSITE_TIME_ZONE
的应用设置。
此设置的值取决于运行函数应用的操作系统和计划。
Operating system | Plan | Value |
---|---|---|
Windows | All | 将该值设置为所需时区的名称,由 Windows 命令 tzutil.exe /L 给定的每个对的第二行指定 |
Linux | 高级 专属 |
Set the value to the name of the desired time zone as shown in the tz database |
Note
WEBSITE_TIME_ZONE
在 TZ
Linux 上运行消耗计划或弹性消耗计划时,目前不受支持。 在这种情况下,设置 WEBSITE_TIME_ZONE
或 TZ
可以创建与 SSL 相关的问题,并导致指标停止为应用工作。
例如,美国东部时间(由 Eastern Standard Time
(Windows) 或 America/New_York
(Linux) 表示)当前在标准时间中使用 UTC-05:00,在夏令时中使用 UTC-04:00。 若要使计时器触发器每天在东部时间上午 10:00 触发,请为函数应用创建一个名为 WEBSITE_TIME_ZONE
的应用设置并将值设置为 Eastern Standard Time
(Windows) 或 America/New_York
(Linux),然后使用以下 NCRONTAB 表达式:
"0 0 10 * * *"
使用 WEBSITE_TIME_ZONE
时,根据特定时区的时间更改调整时间,包括夏令时和标准时间的更改。
TimeSpan
只能对在应用服务计划中运行的函数应用使用 TimeSpan
。
与 NCRONTAB 表达式不同,TimeSpan
值指定各次函数调用之间的时间间隔。 如果函数的运行时间超出了指定的时间间隔,则在函数完成时,计时器会立即再次调用该函数。
以字符串表示,当 TimeSpan
小于 24 时,hh:mm:ss
格式为 hh
。 当前两个数字是 24 或更大的数字时,格式为 dd:hh:mm
。 下面是一些示例:
Example | When triggered |
---|---|
"01:00:00" | every hour |
"00:01:00" | every minute |
"25:00:00:00" | 每 25 天 |
"1.00:00:00" | every day |
Scale-out
如果函数应用横向扩展到多个实例,则在所有实例中只会运行由计时器触发的函数的单个实例。 如果有未完成的调用仍在运行,它将不会再次触发。
共享同一存储的函数应用
如果要在未部署到应用服务的函数应用之间共享存储帐户,则可能需要为每个应用显式分配主机 ID。
Functions version | Setting |
---|---|
2.x(及更高版本) |
AzureFunctionsWebHost__hostid 环境变量 |
1.x |
id in host.json |
可以省略标识值,也可以手动将每个函数应用的标识配置设置为不同的值。
计时器触发器使用存储锁来确保当函数应用横向扩展到多个实例时将只有一个计时器实例。 如果两个函数应用共享相同的标识配置,并且每个函数应用都使用一个计时器触发器,则只有一个计时器运行。
Retry behavior
与队列触发器不同,计时器触发器在函数失败后不会重试。 函数失败时,在计划的下次时间到来前,不会再次调用该函数。
手动调用计时器触发器
Azure Functions 的计时器触发器提供了 HTTP Webhook,可以通过调用它来手动触发函数。 这在以下方案中非常有用。
- Integration testing
- 槽交换是冒烟测试或预热活动的一部分
- 函数的初始部署,以立即在数据库中填充缓存或查找表
若要详细了解如何手动调用计时器触发的函数,请参阅手动运行非 HTTP 触发的函数。
Troubleshooting
有关在计时器触发器未按预期工作的情况下应采取的措施,请参阅调查和报告有关计时器触发功能未触发的问题。
Connections
计时器触发器对 Blob 存储具有隐式依赖项,除非通过 Azure Functions Core Tools 在本地运行。 当应用横向扩展时,系统使用 Blob 存储跨多个实例进行协调。它使用主机存储(AzureWebJobsStorage
)连接访问 Blob 存储。 If you configure the host storage to use an identity-based connection, the identity should have the Storage Blob Data Owner role, which is the default requirement for host storage.