Inicio rápido: Ejecución de tareas programadas mediante Azure Functions

En este artículo, usará Azure Developer CLI (azd) para crear una función activada por temporizador para ejecutar una tarea programada en Azure Functions. Después de comprobar el código localmente, se implementa en una nueva aplicación de funciones sin servidor que se crea en ejecución en un plan de consumo flexible en Azure Functions.

El origen del proyecto usa azd para crear la aplicación de funciones y los recursos relacionados y para implementar el código en Azure. Esta implementación sigue los procedimientos recomendados actuales para implementaciones seguras y escalables de Azure Functions.

De forma predeterminada, el plan flex Consumption sigue un modelo de facturación de pago por uso , lo que significa que puede completar este artículo y solo incurrirá en un pequeño costo de unos pocos centavos de USD o menos en su cuenta de Azure.

En este artículo se admite la versión 4 del modelo de programación de Node.js para Azure Functions.

En este artículo se admite la versión 2 del modelo de programación de Python para Azure Functions.

Prerrequisitos

  • kit para desarrolladores de Java 17
    • Si usa otra versión compatible de Java, debe actualizar la configuración del proyecto.
    • Establezca la variable de entorno JAVA_HOME en la ubicación de instalación de la versión correcta del kit de desarrollo de Java (JDK).
  • Apache Maven 3.8.x

Inicialización del proyecto

Use el azd init comando para crear un proyecto de código local de Azure Functions a partir de una plantilla.

  1. En el terminal local o el símbolo del sistema, ejecute este comando azd init en una carpeta vacía:

    azd init --template functions-quickstart-dotnet-azd-timer -e scheduled-dotnet
    

    Este comando extrae los archivos del proyecto del repositorio de plantillas e inicializa el proyecto en la carpeta actual. La marca -e establece un nombre para el entorno actual. En azd, el entorno mantiene un contexto de implementación único para la aplicación y puede definir más de uno. El nombre del entorno también se usa en el nombre del grupo de recursos que crea en Azure.

  2. Ejecute este comando para ir a la carpeta de la aplicación:

    cd src
    
  3. Cree un archivo denominado local.settings.json en la src carpeta que contiene estos datos JSON:

    {
        "IsEncrypted": false,
        "Values": {
            "AzureWebJobsStorage": "UseDevelopmentStorage=true",
            "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
            "TIMER_SCHEDULE": "*/30 * * * * *"
        }
    }
    

    Este archivo es necesario cuando se ejecuta localmente.

  1. En el terminal local o el símbolo del sistema, ejecute este comando azd init en una carpeta vacía:

    azd init --template functions-quickstart-typescript-azd-timer -e scheduled-ts
    

    Este comando extrae los archivos del proyecto del repositorio de plantillas e inicializa el proyecto en la carpeta actual. La marca -e establece un nombre para el entorno actual. En azd, el entorno mantiene un contexto de implementación único para la aplicación y puede definir más de uno. El nombre del entorno también se usa en el nombre del grupo de recursos que crea en Azure.

  2. Cree un archivo denominado local.settings.json en la src carpeta que contiene estos datos JSON:

    {
        "IsEncrypted": false,
        "Values": {
            "AzureWebJobsStorage": "UseDevelopmentStorage=true",
            "FUNCTIONS_WORKER_RUNTIME": "node",
            "TIMER_SCHEDULE": "*/30 * * * * *"
        }
    }
    

    Este archivo es necesario cuando se ejecuta localmente.

  1. En el terminal local o el símbolo del sistema, ejecute este comando azd init en una carpeta vacía:

    azd init --template functions-quickstart-python-azd-timer -e scheduled-py
    

    Este comando extrae los archivos del proyecto del repositorio de plantillas e inicializa el proyecto en la carpeta actual. La marca -e establece un nombre para el entorno actual. En azd, el entorno mantiene un contexto de implementación único para la aplicación y puede definir más de uno. El nombre del entorno también se usa en el nombre del grupo de recursos que crea en Azure.

  2. Cree un archivo denominado local.settings.json en la src carpeta que contiene estos datos JSON:

    {
        "IsEncrypted": false,
        "Values": {
            "AzureWebJobsStorage": "UseDevelopmentStorage=true",
            "FUNCTIONS_WORKER_RUNTIME": "python",
            "TIMER_SCHEDULE": "*/30 * * * * *"
        }
    }
    

    Este archivo es necesario cuando se ejecuta localmente.

Creación y activación de un entorno virtual

En la carpeta raíz, ejecute estos comandos para crear y activar un entorno virtual denominado .venv:

python3 -m venv .venv
source .venv/bin/activate

Si Python no instala el paquete venv en la distribución de Linux, ejecute el siguiente comando:

sudo apt-get install python3-venv
  1. En el terminal local o el símbolo del sistema, ejecute este comando azd init en una carpeta vacía:

    azd init --template functions-quickstart-java-azd-timer -e scheduled-java
    

    Este comando extrae los archivos del proyecto del repositorio de plantillas e inicializa el proyecto en la carpeta actual. La marca -e establece un nombre para el entorno actual. En azd, el entorno mantiene un contexto de implementación único para la aplicación y puede definir más de uno. El nombre del entorno también se usa en el nombre del grupo de recursos que crea en Azure.

  2. Ejecute este comando para ir a la carpeta de la aplicación:

    cd src
    
  3. Cree un archivo denominado local.settings.json en la src carpeta que contiene estos datos JSON:

    {
        "IsEncrypted": false,
        "Values": {
            "AzureWebJobsStorage": "UseDevelopmentStorage=true",
            "FUNCTIONS_WORKER_RUNTIME": "java",
            "TIMER_SCHEDULE": "*/30 * * * * *"
        }
    }
    

    Este archivo es necesario cuando se ejecuta localmente.

  1. En el terminal local o el símbolo del sistema, ejecute este comando azd init en una carpeta vacía:

    azd init --template functions-quickstart-javascript-azd-timer -e scheduled-js
    

    Este comando extrae los archivos del proyecto del repositorio de plantillas e inicializa el proyecto en la carpeta actual. La marca -e establece un nombre para el entorno actual. En azd, el entorno mantiene un contexto de implementación único para la aplicación y puede definir más de uno. El nombre del entorno también se usa en el nombre del grupo de recursos que crea en Azure.

  2. Cree un archivo denominado local.settings.json en la src carpeta que contiene estos datos JSON:

    {
        "IsEncrypted": false,
        "Values": {
            "AzureWebJobsStorage": "UseDevelopmentStorage=true",
            "FUNCTIONS_WORKER_RUNTIME": "node",
            "TIMER_SCHEDULE": "*/30 * * * * *"
        }
    }
    

    Este archivo es necesario cuando se ejecuta localmente.

  1. En el terminal local o el símbolo del sistema, ejecute este comando azd init en una carpeta vacía:

    azd init --template functions-quickstart-powershell-azd-timer -e scheduled-ps
    

    Este comando extrae los archivos del proyecto del repositorio de plantillas e inicializa el proyecto en la carpeta actual. La marca -e establece un nombre para el entorno actual. En azd, el entorno mantiene un contexto de implementación único para la aplicación y puede definir más de uno. El nombre del entorno también se usa en el nombre del grupo de recursos que crea en Azure.

  2. Ejecute este comando para ir a la carpeta de la aplicación:

    cd src
    
  3. Cree un archivo denominado local.settings.json en la src carpeta que contiene estos datos JSON:

    {
        "IsEncrypted": false,
        "Values": {
            "AzureWebJobsStorage": "UseDevelopmentStorage=true",
            "FUNCTIONS_WORKER_RUNTIME": "powershell",
            "TIMER_SCHEDULE": "*/30 * * * * *"
        }
    }
    

    Este archivo es necesario cuando se ejecuta localmente.

Ejecución en el entorno local

  1. En una ventana de terminal independiente, inicie el emulador de almacenamiento de Azurite:

    azurite
    

    El proceso de host local de Functions utiliza el emulador de Azurite para la conexión de almacenamiento interna (AzureWebJobsStorage) requerida por el tiempo de ejecución.

  1. Ejecute este comando desde la carpeta de la aplicación en un terminal o símbolo del sistema:

    func start
    
  1. Ejecute este comando desde la carpeta de la aplicación en un terminal o símbolo del sistema:

    mvn clean package
    mvn azure-functions:run
    
  1. Ejecute este comando desde la carpeta de la aplicación en un terminal o símbolo del sistema:

    npm install
    func start  
    
  1. Ejecute este comando desde la carpeta de la aplicación en un terminal o símbolo del sistema:

    npm install
    npm start  
    
  1. Cuando el host de Functions se inicia en la carpeta del proyecto local, escribe información sobre la función desencadenada por el temporizador en la salida del terminal. Debería ver que la función desencadenada por el temporizador se ejecuta según la programación definida en el código.

    La programación predeterminada es */30 * * * * *, que se ejecuta cada 30 segundos.

  2. Cuando haya terminado, presione Ctrl+C en la ventana del terminal para detener el proceso de host de func.exe.

  1. Ejecute deactivate para apagar el entorno virtual.

Revisión del código (opcional)

Puede revisar el código que define la función de desencadenador de temporizador:

using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Extensions.Timer;
using Microsoft.Extensions.Logging;

namespace Company.Function
{
    public class timerFunction
    {
        private readonly ILogger _logger;

        public timerFunction(ILoggerFactory loggerFactory)
        {
            _logger = loggerFactory.CreateLogger<timerFunction>();
        }

        [Function("timerFunction")]
        public void Run(
            [TimerTrigger("%TIMER_SCHEDULE%", RunOnStartup = true)] TimerInfo myTimer,
            FunctionContext context
        )
        {
            _logger.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");

            if (myTimer.IsPastDue)
            {
                _logger.LogWarning("The timer is running late!");
            }
        }
    }
}

Puede revisar el proyecto de plantilla completo aquí.

package com.function;

import com.microsoft.azure.functions.ExecutionContext;
import com.microsoft.azure.functions.annotation.FunctionName;
import com.microsoft.azure.functions.annotation.TimerTrigger;
import java.time.LocalDateTime;

/**
 * Timer-triggered Azure Function that demonstrates scheduled execution.
 */
public class TimerFunction {
    @FunctionName("timerFunction")
    public void run(
            @TimerTrigger(name = "timerInfo", schedule = "%TIMER_SCHEDULE%") String timerInfo,
            final ExecutionContext context) {

        context.getLogger().info("Java Timer trigger function executed at: " + LocalDateTime.now());

        if (timerInfo != null && timerInfo.contains("\"isPastDue\":true")) {
            context.getLogger().warning("The timer is running late!");
        }
    }
}

Puede revisar el proyecto de plantilla completo aquí.

const { app } = require('@azure/functions');
async function timerFunction(myTimer, context) {
    context.log(`JavaScript Timer trigger function executed at: ${new Date().toISOString()}`);

    if (myTimer.isPastDue) {
        context.warn("The timer is running late!");
    }
}

app.timer('timerFunction', {
    schedule: '%TIMER_SCHEDULE%',
    runOnStartup: true,
    handler: timerFunction,
});

Puede revisar el proyecto de plantilla completo aquí.

import { app, InvocationContext, Timer } from '@azure/functions';

export async function timerFunction(myTimer: Timer, context: InvocationContext): Promise<void> {
    context.log(`TypeScript Timer trigger function executed at: ${new Date().toISOString()}`);

    if (myTimer.isPastDue) {
        context.warn("The timer is running late!");
    }
}

app.timer('timerFunction', {
    schedule: '%TIMER_SCHEDULE%',
    runOnStartup: true,
    handler: timerFunction
});

Puede revisar el proyecto de plantilla completo aquí.

# 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 executed at: $currentUTCtime"

El desencadenador de temporizador se define en el function.json correspondiente.

Puede revisar el proyecto de plantilla completo aquí.

import datetime
import logging

import azure.functions as func

# Create the function app instance
app = func.FunctionApp()

@app.timer_trigger(schedule="%TIMER_SCHEDULE%", 
                   arg_name="mytimer", 
                   run_on_startup=True,
                   use_monitor=False) 
def timer_function(mytimer: func.TimerRequest) -> None:
    utc_timestamp = datetime.datetime.now(datetime.timezone.utc).isoformat()
    
    logging.info(f'Python timer trigger function executed at: {utc_timestamp}')
    
    if mytimer.past_due:
        logging.warning('The timer is running late!')

Puede revisar el proyecto de plantilla completo aquí.

Sugerencia

La runOnStartup opción es útil durante el desarrollo y las pruebas porque la función se ejecuta inmediatamente cuando se inicia el host. En producción, debe establecerlo en false para evitar ejecuciones inesperadas durante las implementaciones o reinicios.

Después de comprobar la función localmente, es el momento de publicarla en Azure.

Implementación en Azure

Este proyecto usa archivos Bicep y el comando azd up para crear una implementación segura en una nueva aplicación de funciones en un plan de consumo flexible que siga los procedimientos recomendados.

  1. Ejecute este comando para que azd cree los recursos de Azure necesarios en Azure e implemente el proyecto de código en la nueva aplicación de funciones:

    azd up
    

    La carpeta raíz contiene el azure.yamlarchivo de definición de requerido por azd.

    Si aún no ha iniciado sesión, se le pedirá que se autentique con su cuenta de Azure.

  2. Cuando se le solicite, proporcione estos parámetros de implementación necesarios:

    Parámetro Description
    Suscripción a Azure Suscripción en la que se crean los recursos.
    Ubicación de Azure Región de Azure en la que se va a crear el grupo de recursos que contiene los nuevos recursos de Azure. Solo se muestran las regiones que admiten actualmente el Plan de consumo flexible.

    El comando azd up usa la respuesta a estos mensajes con los archivos de configuración de Bicep para completar estas tareas de implementación:

    • Cree y configure estos recursos de Azure necesarios (equivalente a azd provision):

      • Plan de consumo flexible y aplicación de funciones
      • Azure Storage (obligatorio) y Application Insights (recomendado)
      • Directivas y roles de acceso para la cuenta
      • Conexiones de servicio a servicio mediante identidades administradas (en lugar de cadenas de conexión almacenadas)
      • Red virtual para ejecutar de forma segura tanto la aplicación de funciones como los demás recursos de Azure
    • Empaquete e implemente el código en el contenedor de implementación (equivalente a azd deploy). A continuación, la aplicación se inicia y se ejecuta en el paquete implementado.

    Una vez que el comando se complete correctamente, verá vínculos a los recursos que creó.

Comprobación de la implementación

Una vez completada la implementación, la función de desencadenador de temporizador comienza automáticamente a ejecutarse en Azure en función de su programación.

  1. En Azure Portal, vaya a la nueva aplicación de funciones.

  2. Seleccione Flujo de registro en el menú de la izquierda para supervisar las ejecuciones de funciones en tiempo real.

  3. Debería ver las entradas de registro que muestran la ejecución de su función de temporizador de acuerdo con su programación.

Reimplementación del código

Ejecute el azd up comando tantas veces como sea necesario aprovisionar los recursos de Azure e implementar actualizaciones de código en la aplicación de funciones.

Nota:

El paquete de implementación más reciente siempre sobrescribe los archivos de código implementados.

Las respuestas iniciales a azd mensajes y las variables de entorno generadas por azd se almacenan localmente en el entorno con nombre. Use el comando azd env get-values para revisar todas las variables del entorno que se usaron al crear recursos de Azure.

Limpieza de recursos

Cuando haya terminado de trabajar con la aplicación de funciones y los recursos relacionados, use este comando para eliminar la aplicación de funciones y sus recursos relacionados de Azure y evitar incurrir en costos adicionales:

azd down --no-prompt

Nota:

La --no-prompt opción indica azd que elimine el grupo de recursos sin una confirmación de usted.

Este comando no afecta al proyecto de código local.