Desencadenador de temporizador para Azure Functions

En este artículo se explica cómo usar desencadenadores de temporizador en Azure Functions. Con un desencadenador de temporizador puede ejecutar una función de forma programada.

Esta es la información de referencia para desarrolladores de Azure Functions. Si está familiarizado con Azure Functions, comience con los siguientes recursos:

Para información sobre cómo ejecutar manualmente una función desencadenada por un temporizador, consulte Ejecución manual de una función no desencadenada por HTTP.

En todos los entornos de desarrollo, se proporciona automáticamente compatibilidad para este enlace. No tiene que instalar el paquete manualmente ni que registrar la extensión.

El código fuente del paquete de extensión del temporizador está en el repositorio azure-webjobs-sdk-extensions de GitHub.

Ejemplo

En este ejemplo se muestra una función de C# que se ejecuta cada vez que los minutos tienen un valor divisible entre cinco. Por ejemplo, cuando la función se inicia a las 18:55:00, la siguiente ejecución es a las 19:00:00. El objeto TimerInfo se pasa a la función.

Se puede crear una función C# mediante uno de los siguientes modos de C#:

  • Biblioteca de clases en proceso: función de C# compilada que se ejecuta en el mismo proceso que Functions Runtime.
  • Biblioteca de clases de procesos de trabajo aislados: función de C# compilada que se ejecuta en un proceso de trabajo aislado del entorno de ejecución. Se requiere un proceso de trabajo aislado para admitir funciones de C# que se ejecutan en versiones de .NET que no son LTS y .NET Framework.
  • Script de C#: se usa principalmente al crear funciones de C# en Azure Portal.
[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}");
}

El la función de ejemplo siguiente se desencadena y se ejecuta cada cinco minutos. La anotación @TimerTrigger en la función define la programación con el mismo formato de cadena que las expresiones CRON.

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

En el ejemplo siguiente se muestra un enlace de desencadenador de temporizador en un archivo function.json y un código de función que usa el enlace, donde se pasa a la función una instancia que representa el temporizador. La función escribe un registro que indica si esta invocación de función se debe a una repetición de la programación no ejecutada.

Estos son los datos de enlace del archivo function.json:

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

Este es el código de JavaScript:

module.exports = async 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);   
};

A continuación se muestra el código de la función de temporizador en el archivo 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"

Este es el código Python, donde el objeto pasado a la función es de tipo azure.functions.TimerRequest.

import datetime
import logging

import azure.functions as func


def main(mytimer: func.TimerRequest) -> None:
    utc_timestamp = datetime.datetime.now(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)

Atributos

En proceso La biblioteca de C# usa TimerTriggerAttribute de Microsoft.Azure.WebJobs.Extensions, mientras que la biblioteca de C# de Procesos de trabajos aislados usa TimerTriggerAttribute de Microsoft.Azure.Functions.Worker.Extensions.Timer para definir la función.

El script de C#, en su lugar, usa un archivo de configuración function.json.

Propiedad de atributo Descripción
Programación Una expresión CRON o un valor TimeSpan. TimeSpan solamente se puede usar para una aplicación de función que se ejecuta en un plan de App Service. Puede colocar la expresión de programación en una configuración de aplicación y establecer esta propiedad en el nombre de dicha configuración encapsulado en signos %, como %ScheduleAppSetting%.
RunOnStartup Si true, la función se invoca cuando se inicia el entorno de ejecución. Por ejemplo, el entorno de ejecución se inicia cuando la aplicación de función se reactiva después de estar inactiva por inactividad, cuando la aplicación de función se reinicia debido a cambios de función y cuando la aplicación de función se escala horizontalmente. Úselo con precaución.RunOnStartup rara vez o nunca debería estar configurado como true, especialmente en producción.
useMonitor Establezca esta propiedad en true o false para indicar si la programación se debe supervisar. La supervisión de la programación conserva las apariciones de programación para ayudar a garantizar que la programación se mantiene correctamente aunque las instancias de aplicación de función se reinicien. Si no se establece explícitamente, el valor predeterminado es true para las programaciones que tienen un intervalo de periodicidad superior o igual a 1 minuto. Para las programaciones que se desencadenan más de una vez por minuto, el valor predeterminado es false.

anotaciones

La anotación @TimerTrigger en la función define la schedule con el mismo formato de cadena que las expresiones CRON. La anotación admite los valores siguientes:

Configuración

En la siguiente tabla se explican las propiedades de configuración de enlace que se establecen en el archivo function.json.

Propiedad de function.json Descripción
type Debe establecerse en "timerTrigger". Esta propiedad se establece automáticamente cuando se crea el desencadenador en Azure Portal.
direction Debe establecerse en "in". Esta propiedad se establece automáticamente cuando se crea el desencadenador en Azure Portal.
name Nombre de la variable que representa el objeto de temporizador en el código de la función.
schedule Una expresión CRON o un valor TimeSpan. TimeSpan solamente se puede usar para una aplicación de función que se ejecuta en un plan de App Service. Puede colocar la expresión de programación en una configuración de aplicación y establecer esta propiedad en el nombre de dicha configuración encapsulado en signos % , como en este ejemplo: "%ScheduleAppSetting%".
runOnStartup Si true, la función se invoca cuando se inicia el entorno de ejecución. Por ejemplo, el entorno de ejecución se inicia cuando la aplicación de función se reactiva después de estar inactiva por inactividad, cuando la aplicación de función se reinicia debido a cambios de función y cuando la aplicación de función se escala horizontalmente. Úselo con precaución.RunOnStartup rara vez o nunca debería estar configurado como true, especialmente en producción.
useMonitor Establezca esta propiedad en true o false para indicar si la programación se debe supervisar. La supervisión de la programación conserva las apariciones de programación para ayudar a garantizar que la programación se mantiene correctamente aunque las instancias de aplicación de función se reinicien. Si no se establece explícitamente, el valor predeterminado es true para las programaciones que tienen un intervalo de periodicidad superior o igual a 1 minuto. Para las programaciones que se desencadenan más de una vez por minuto, el valor predeterminado es false.

Cuando esté desarrollando localmente, agregue la configuración de la aplicación en el archivo local.settings.json de la colección .

Precaución

No establezca runOnStartup en true en producción. Con esta configuración, el código se ejecuta en momentos altamente impredecibles. En ciertas configuraciones de producción, estas ejecuciones adicionales pueden dar lugar a costos considerablemente mayores para las aplicaciones hospedadas en un plan de consumo. Por ejemplo, con runOnStartup habilitado, se invoca al desencadenador cada vez que se escala la aplicación de función. Asegúrese de comprender perfectamente el comportamiento de producción de las funciones antes de habilitar runOnStartup en producción.

Consulte la sección de ejemplos para ver ejemplos completos.

Uso

Cuando se invoca una función de desencadenador de temporizador, se pasa a esta un objeto de temporizador. La siguiente función JSON es un ejemplo que representa el objeto de temporizador.

{
    "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
}

La propiedad isPastDue es true cuando la invocación de función actual es posterior a la programada. Por ejemplo, un reinicio de aplicación de función podría provocar la ausencia de una invocación.

Expresiones NCRONTAB

Azure Functions usa la biblioteca NCronTab para interpretar las expresiones NCRONTAB. Una expresión NCRONTAB es similar a una expresión CRON, excepto en que incluye un sexto campo adicional al comienzo para usarlo con una precisión de segundos:

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

Cada campo puede tener uno de los siguientes tipos de valores:

Tipo Ejemplo Cuándo se desencadena
Un valor específico 0 5 * * * * Una vez cada hora del día en el minuto 5 de cada hora
Todos los valores (*) 0 * 5 * * * En cada minuto de la hora, a partir de la hora 5
Un intervalo (operador -) 5-7 * * * * * Tres veces en un minuto: en los segundos del 5 al 7 durante cada minuto de cada hora de cada día
Un conjunto de valores (operador ,) 5,8,10 * * * * * Tres veces en un minuto: en los segundos 5, 8 y 10 durante cada minuto de cada hora de cada día
Un valor de intervalo (operador /) 0 */5 * * * * 12 veces en una hora: en el segundo 0 de cada quinto minuto de cada hora de cada día

Para especificar meses o días puede usar valores numéricos, nombres o abreviaturas de nombres:

  • Para los días, los valores numéricos van de 0 a 6, donde 0 comienza con el domingo.
  • Los nombres están en inglés. Por ejemplo: Monday, January.
  • Los nombres no distinguen mayúsculas de minúsculas.
  • Los nombres se pueden abreviar. La longitud recomendada para la abreviatura es de tres letras. Por ejemplo: Mon, Jan.

Ejemplos de NCRONTAB

Estos son algunos ejemplos de expresiones NCRONTAB que puede usar para el desencadenador de temporizador en Azure Functions.

Ejemplo Cuándo se desencadena
0 */5 * * * * Una vez cada cinco minutos
0 0 * * * * Una vez al principio de cada hora
0 0 */2 * * * Una vez cada dos horas
0 0 9-17 * * * Una vez cada hora de 9 a. m. a 5 p. m.
0 30 9 * * * A las 9:30 a. m. todos los días
0 30 9 * * 1-5 A las 9:30 a. m. cada día de la semana
0 30 9 * Jan Mon A las 9:30 a. m. todos los lunes en enero

Nota

La expresión NCRONTAB admite el formato de cinco campos y seis campos. La posición del sexto campo es un valor para los segundos que se coloca al principio de la expresión.

Zonas horarias de NCRONTAB

Los números de una expresión CRON hacen referencia a una hora y fecha, no un intervalo de tiempo. Por ejemplo, un 5 en el campo hour hace referencia a las 5:00 a. m., no a cada 5 horas.

La zona horaria predeterminada que se usa con las expresiones CRON es la Hora universal coordinada (UTC). Para que la expresión CRON se base en otra zona horaria, cree una configuración de aplicación para la aplicación de función denominada WEBSITE_TIME_ZONE.

El valor de esta opción de configuración depende del sistema operativo y del plan en el que se ejecuta la aplicación de funciones.

Sistema operativo Plan Value
Windows All Establezca como valor el nombre de la zona horaria que desea, tal como aparece en la segunda línea de los pares que proporciona el comando de Windows tzutil.exe /L
Linux Premium
Dedicado
Establezca el valor en el nombre de la zona horaria deseada como se muestra en tz database.

Nota

El plan de Consumo para Linux actualmente no admite WEBSITE_TIME_ZONE.

Por ejemplo, la hora del este de EE. UU. (que se representa mediante Eastern Standard Time en Windows o America/New_York en Linux) usa actualmente UTC-05:00 mientras está vigente la hora estándar y UTC-04:00 durante el horario de verano. Para que un desencadenador de temporizador lo ponga en marcha a las 10:00 AM, hora del este, todos los días,cree una configuración de aplicación para la aplicación de funciones denominada WEBSITE_TIME_ZONE, establezca el valor en Eastern Standard Time (Windows) o America/New_York (Linux) y, a continuación, use la siguiente expresión NCRONTAB:

"0 0 10 * * *"

Si usa WEBSITE_TIME_ZONE, la hora se ajusta a los cambios de hora de la zona horaria concreta, lo que incluye el horario de verano, y los cambios en la hora estándar.

TimeSpan

TimeSpan solamente se puede usar para una aplicación de función que se ejecuta en un plan de App Service.

A diferencia de una expresión CRON, un valor TimeSpan especifica el intervalo de tiempo entre cada invocación de función. Cuando una función se completa después de ejecutarse más tiempo del intervalo especificado, el temporizador vuelve a invocar inmediatamente a la función.

Expresado como una cadena, el formato TimeSpan es hh:mm:ss cuando hh es menor que 24. Si los dos primeros dígitos son 24 o un valor superior, el formato es dd:hh:mm. Estos son algunos ejemplos:

Ejemplo Cuándo se desencadena
"01:00:00" Cada hora
"00:01:00" Cada minuto
"25:00:00:00" cada 25 días
"1.00:00:00" Todos los días

Escalado horizontal

Si una aplicación de función se escala horizontalmente a varias instancias, una sola instancia de una función desencadenada por el temporizador se ejecuta en todas las instancias. No se volverá a desencadenar aunque se siga ejecutando una invocación pendiente.

Aplicaciones de función que comparten almacenamiento

Si comparte cuentas de almacenamiento en aplicaciones de funciones que no se implementan en app service, es posible que tenga que asignar explícitamente un identificador de host a cada aplicación.

Versión de Functions Configuración
2.x (y versiones posteriores) Variable de entorno AzureFunctionsWebHost__hostid
1.x id en host.json

Puede omitir el valor de identificación o establecer manualmente la configuración de identificación de cada aplicación de funciones en otro valor.

El desencadenador de temporizador utiliza un bloqueo de almacenamiento para asegurarse de que solo hay una instancia de temporizador cuando una aplicación de función se escala a varias instancias. Si dos aplicaciones de función comparten la misma configuración de identificación y cada una usa un desencadenador de temporizador, solo se ejecutará un temporizador.

Comportamiento de reintento

A diferencia del desencadenador de cola, el desencadenador de temporizador no vuelve a realizar el intento después de que se produce un error en una función. Cuando se produce un error en una función, no se la llamará nuevamente hasta la próxima vez en la programación.

Invocación manual de un desencadenador de temporizador

El desencadenador de temporizador de Azure Functions proporciona un webhook HTTP que se puede invocar para desencadenar manualmente la función. Esto puede resultar extremadamente útil en los siguientes escenarios.

  • Pruebas de integración
  • Intercambios de ranura como parte de una prueba de humo o una actividad de calentamiento
  • Implementación inicial de una función para rellenar inmediatamente una caché o una tabla de búsqueda en una base de datos

Consulte Ejecución manual de una función no desencadenada por HTTP para obtener más información sobre cómo invocar manualmente una función desencadenada por un temporizador.

Solución de problemas

Para obtener información sobre qué hacer cuando el desencadenador del temporizador no funcione según lo esperado, consulte Investigating and reporting issues with timer triggered functions not firing (Investigación y notificación de problemas en que las funciones desencadenadas por el temporizador no se activan).

Pasos siguientes