Início Rápido: Executar tarefas agendadas usando o Azure Functions

Neste artigo, você usa a CLI do Desenvolvedor do Azure (azd) para criar uma função de gatilho de temporizador para executar uma tarefa agendada no Azure Functions. Depois de verificar o código localmente, você o implanta em um novo aplicativo de funções sem servidor criado em execução em um plano de Consumo Flex no Azure Functions.

A fonte do projeto usa azd para criar o aplicativo de funções e recursos relacionados e implantar seu código no Azure. Esta implantação segue as melhores práticas atuais para implantações seguras e escaláveis do Azure Functions.

Por padrão, o plano Flex Consumption segue um modelo de cobrança pague pelo que usar, o que significa que você pode concluir este artigo e incorrerá apenas em um custo de apenas alguns centavos de dólar ou menos em sua conta do Azure.

Este artigo dá suporte à versão 4 do modelo de programação Node.js para Azure Functions.

Este artigo dá suporte à versão 2 do modelo de programação Python para Azure Functions.

Pré-requisitos

Inicializar o projeto

Use o azd init comando para criar um projeto de código local do Azure Functions a partir de um modelo.

  1. No seu terminal ou prompt de comando local, execute esse azd init comando em uma pasta vazia:

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

    Esse comando extrai os arquivos de projeto do repositório de modelos e inicializa o projeto na pasta atual. O sinalizador -e define um nome para o ambiente atual. Em azd, o ambiente mantém um contexto de implantação exclusivo para seu aplicativo e você pode definir mais de um. O nome do ambiente também é usado no nome do grupo de recursos que você cria no Azure.

  2. Execute este comando para navegar até a pasta do aplicativo:

    cd src
    
  3. Crie um arquivo chamado local.settings.json na pasta src que contenha esses dados JSON:

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

    Este arquivo é necessário ao executar localmente.

  1. No seu terminal ou prompt de comando local, execute esse azd init comando em uma pasta vazia:

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

    Esse comando extrai os arquivos de projeto do repositório de modelos e inicializa o projeto na pasta atual. O sinalizador -e define um nome para o ambiente atual. Em azd, o ambiente mantém um contexto de implantação exclusivo para seu aplicativo e você pode definir mais de um. O nome do ambiente também é usado no nome do grupo de recursos que você cria no Azure.

  2. Crie um arquivo chamado local.settings.json na pasta src que contenha esses dados JSON:

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

    Este arquivo é necessário ao executar localmente.

  1. No seu terminal ou prompt de comando local, execute esse azd init comando em uma pasta vazia:

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

    Esse comando extrai os arquivos de projeto do repositório de modelos e inicializa o projeto na pasta atual. O sinalizador -e define um nome para o ambiente atual. Em azd, o ambiente mantém um contexto de implantação exclusivo para seu aplicativo e você pode definir mais de um. O nome do ambiente também é usado no nome do grupo de recursos que você cria no Azure.

  2. Crie um arquivo chamado local.settings.json na pasta src que contenha esses dados JSON:

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

    Este arquivo é necessário ao executar localmente.

Criar e ativar um ambiente virtual

Na pasta raiz, execute estes comandos para criar e ativar um ambiente virtual chamado .venv:

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

Se o Python não instalar o pacote venv na distribuição do Linux, execute o seguinte comando:

sudo apt-get install python3-venv
  1. No seu terminal ou prompt de comando local, execute esse azd init comando em uma pasta vazia:

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

    Esse comando extrai os arquivos de projeto do repositório de modelos e inicializa o projeto na pasta atual. O sinalizador -e define um nome para o ambiente atual. Em azd, o ambiente mantém um contexto de implantação exclusivo para seu aplicativo e você pode definir mais de um. O nome do ambiente também é usado no nome do grupo de recursos que você cria no Azure.

  2. Execute este comando para navegar até a pasta do aplicativo:

    cd src
    
  3. Crie um arquivo chamado local.settings.json na pasta src que contenha esses dados JSON:

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

    Este arquivo é necessário ao executar localmente.

  1. No seu terminal ou prompt de comando local, execute esse azd init comando em uma pasta vazia:

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

    Esse comando extrai os arquivos de projeto do repositório de modelos e inicializa o projeto na pasta atual. O sinalizador -e define um nome para o ambiente atual. Em azd, o ambiente mantém um contexto de implantação exclusivo para seu aplicativo e você pode definir mais de um. O nome do ambiente também é usado no nome do grupo de recursos que você cria no Azure.

  2. Crie um arquivo chamado local.settings.json na pasta src que contenha esses dados JSON:

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

    Este arquivo é necessário ao executar localmente.

  1. No seu terminal ou prompt de comando local, execute esse azd init comando em uma pasta vazia:

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

    Esse comando extrai os arquivos de projeto do repositório de modelos e inicializa o projeto na pasta atual. O sinalizador -e define um nome para o ambiente atual. Em azd, o ambiente mantém um contexto de implantação exclusivo para seu aplicativo e você pode definir mais de um. O nome do ambiente também é usado no nome do grupo de recursos que você cria no Azure.

  2. Execute este comando para navegar até a pasta do aplicativo:

    cd src
    
  3. Crie um arquivo chamado local.settings.json na pasta src que contenha esses dados JSON:

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

    Este arquivo é necessário ao executar localmente.

Executar no seu ambiente local

  1. Em uma janela de terminal separada, inicie o emulador de armazenamento do Azurite:

    azurite
    

    O processo de host local do Functions usa o emulador do Azurite para a conexão de armazenamento interna (AzureWebJobsStorage) exigida pelo runtime.

  1. Execute este comando da pasta do seu aplicativo em um terminal ou prompt de comando:

    func start
    
  1. Execute este comando da pasta do seu aplicativo em um terminal ou prompt de comando:

    mvn clean package
    mvn azure-functions:run
    
  1. Execute este comando da pasta do seu aplicativo em um terminal ou prompt de comando:

    npm install
    func start  
    
  1. Execute este comando da pasta do seu aplicativo em um terminal ou prompt de comando:

    npm install
    npm start  
    
  1. Quando o host do Functions é iniciado na pasta do projeto local, ele grava informações sobre a sua função disparada pelo Temporizador na saída do terminal. Você deverá ver sua função disparada pelo Temporizador ser executada com base na agenda definida em seu código.

    O agendamento padrão é */30 * * * * *, que é executado a cada 30 segundos.

  2. Quando terminar, pressione Ctrl+C na janela do terminal para interromper o processo do host func.exe.

  1. Execute deactivate para desligar o ambiente virtual.

Examinar o código (opcional)

Você pode examinar o código que define a função de gatilho do 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!");
            }
        }
    }
}

Você pode examinar o projeto de modelo completo aqui.

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

Você pode examinar o projeto de modelo completo aqui.

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

Você pode examinar o projeto de modelo completo aqui.

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

Você pode examinar o projeto de modelo completo aqui.

# 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"

O gatilho de temporizador é definido no function.json correspondente.

Você pode examinar o projeto de modelo completo aqui.

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!')

Você pode examinar o projeto de modelo completo aqui.

Dica

A runOnStartup opção é útil durante o desenvolvimento e teste porque a função é executada imediatamente quando o host é iniciado. Na produção, você deve definir isso para false a fim de evitar execuções inesperadas durante desdobramentos ou reinicializações.

Depois de verificar sua função localmente, é hora de publicá-la no Azure.

Publicar no Azure

Este projeto utiliza arquivos Bicep e o comando azd up para criar uma implantação segura em um novo aplicativo de função dentro de um plano Consumo Flexível, seguindo as melhores práticas.

  1. Execute este comando para que azd crie os recursos necessários do Azure no Azure e implante seu projeto de código no novo aplicativo de funções:

    azd up
    

    A pasta raiz contém o arquivo de definição azure.yaml necessário para azd.

    Se você ainda não estiver conectado, será solicitado que você se autentique com sua conta do Azure.

  2. Quando solicitado, forneça esses parâmetros de implantação obrigatórios:

    Parâmetro Description
    Assinatura do Azure Assinatura na qual seus recursos serão criados.
    Localização do Azure Região do Azure na qual criar o grupo de recursos que contém os novos recursos do Azure. Somente regiões que atualmente dão suporte para o plano de Consumo Flex são mostradas.

    O comando azd up usa sua resposta a esses prompts com os arquivos de configuração Bicep para concluir estas tarefas de implantação:

    • Criar e configurar esses recursos do Azure necessários (equivalente a azd provision):

      • plano de Consumo Flex e aplicativo de funções
      • Armazenamento do Microsoft Azure (obrigatório) e Application Insights (recomendado)
      • Políticas de acesso e funções para sua conta
      • Conexões de serviço a serviço usando identidades gerenciadas (em vez de cadeias de conexão armazenadas)
      • Rede virtual para executar com segurança tanto o aplicativo de funções quanto os outros recursos do Azure
    • Empacotar e implantar seu código para o contêiner de implantação (equivalente a azd deploy). O aplicativo é então iniciado e executa no pacote implantado.

    Após o comando ser concluído com sucesso, você verá links para os recursos que criou.

Verificar a implantação

Após a conclusão da implantação, a função de disparo do temporizador começa a ser executada automaticamente no Azure de acordo com seu cronograma.

  1. No portal do Azure, acesse seu novo aplicativo de funções.

  2. Selecione o fluxo de log no menu esquerdo para monitorar as execuções da função em tempo real.

  3. Você deve ver as entradas de log que mostram a função de gatilho do Temporizador em execução de acordo com a sua agenda.

Reimplantar seu código

Execute o azd up comando quantas vezes precisar para provisionar seus recursos do Azure e implantar atualizações de código em seu aplicativo de funções.

Observação

Os arquivos de código implantados são sempre sobrescritos pelo pacote de implantação mais recente.

Suas respostas iniciais aos prompts azd e quaisquer variáveis de ambiente geradas por azd são armazenadas localmente no seu ambiente nomeado. Use o comando azd env get-values para revisar todas as variáveis no seu ambiente que foram usadas ao criar recursos do Azure.

Limpar os recursos

Quando terminar de trabalhar com seu aplicativo de funções e recursos relacionados, use este comando para excluir o aplicativo de funções e seus recursos relacionados do Azure e evitar incorrer em custos adicionais:

azd down --no-prompt

Observação

A opção --no-prompt instrui azd a excluir seu grupo de recursos sem uma confirmação sua.

Este comando não afeta seu projeto de código local.