Início Rápido: Construa um fluxo de trabalho sem servidor usando Durable Functions

Neste início rápido, utilizam-se as ferramentas de linha de comandos do Azure Developer para construir um fluxo de trabalho serverless que orquestra múltiplas tarefas executadas em paralelo. Crias recursos no Azure, verificas o código localmente e depois implementas-no numa nova aplicação de funções serverless a correr num plano Flex Consumption no Funções do Azure.

O projeto utiliza o Azure Developer CLI (azd) para simplificar a implementação do seu código no Azure. Esta implementação segue as melhores práticas atuais para implementações Funções do Azure seguras e escaláveis. Este início rápido demonstra o padrão fan-out/fan-in em Durable Functions, uma extensão que orquestra fluxos de trabalho com estado e execução persistente. O exemplo utiliza o Durable Task Scheduler, um backend totalmente gerido para Durable Functions que substitui o backend do Armazenamento do Azure. O exemplo recolhe os títulos dos artigos em paralelo — a orquestração ramifica-se para várias atividades a serem executadas em simultâneo, depois reconverge para agregar os resultados.

Por padrão, o plano Flex Consumption segue um modelo de faturação paga pelo que usa, o que significa que completar este início rápido implica um pequeno custo de alguns cêntimos de dólar ou menos na sua conta da Azure.

Pré-requisitos

Inicializar o projeto

Use o azd init comando para criar um projeto local de código de Funções Duráveis a partir de um modelo.

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

    azd init --template durable-functions-quickstart-dotnet-azd -e dfquickstart-dotnet
    

    Este comando retira os ficheiros do projeto do repositório template e inicializa o projeto numa nova pasta. O -e sinalizador define um nome para o ambiente atual. Em azd, o ambiente mantém um contexto de implementação único para a sua aplicação, e pode definir mais do que um. O nome do ambiente também é usado no nome do grupo de recursos que crias no Azure.

  2. Muda para o diretório do projeto e depois navega até à fanoutfanin pasta da app:

    cd durable-functions-quickstart-dotnet-azd/fanoutfanin
    
  1. No terminal local ou prompt de comando, execute este azd init comando em uma pasta vazia:

    azd init --template durable-functions-quickstart-python-azd -e dfquickstart-python
    

    Este comando retira os ficheiros do projeto do repositório template e inicializa o projeto numa nova pasta. O -e sinalizador define um nome para o ambiente atual. Em azd, o ambiente mantém um contexto de implementação único para a sua aplicação, e pode definir mais do que um. O nome do ambiente também é usado no nome do grupo de recursos que crias no Azure.

  2. Muda para o diretório do projeto e depois navega até à src pasta da app:

    cd durable-functions-quickstart-python-azd/src
    
  1. No terminal local ou prompt de comando, execute este azd init comando em uma pasta vazia:

    azd init --template durable-functions-quickstart-typescript-azd -e dfquickstart-typescript
    

    Este comando retira os ficheiros do projeto do repositório template e inicializa o projeto numa nova pasta. O -e sinalizador define um nome para o ambiente atual. Em azd, o ambiente mantém um contexto de implementação único para a sua aplicação, e pode definir mais do que um. O nome do ambiente também é usado no nome do grupo de recursos que crias no Azure.

  2. Muda para o diretório do projeto e depois navega até à src pasta da app:

    cd durable-functions-quickstart-typescript-azd/src
    
  1. No terminal local ou prompt de comando, execute este azd init comando em uma pasta vazia:

    azd init --template durable-functions-quickstart-java-azd -e dfquickstart-java
    

    Este comando retira os ficheiros do projeto do repositório template e inicializa o projeto numa nova pasta. O -e sinalizador define um nome para o ambiente atual. Em azd, o ambiente mantém um contexto de implementação único para a sua aplicação, e pode definir mais do que um. O nome do ambiente também é usado no nome do grupo de recursos que crias no Azure.

  2. Mude para o diretório do projeto:

    cd durable-functions-quickstart-java-azd
    
  1. No terminal local ou prompt de comando, execute este azd init comando em uma pasta vazia:

    azd init --template durable-functions-quickstart-javascript-azd -e dfquickstart-javascript
    

    Este comando retira os ficheiros do projeto do repositório template e inicializa o projeto numa nova pasta. O -e sinalizador define um nome para o ambiente atual. Em azd, o ambiente mantém um contexto de implementação único para a sua aplicação, e pode definir mais do que um. O nome do ambiente também é usado no nome do grupo de recursos que crias no Azure.

  2. Muda para o diretório do projeto e depois navega até à src pasta da app:

    cd durable-functions-quickstart-javascript-azd/src
    
  1. No terminal local ou prompt de comando, execute este azd init comando em uma pasta vazia:

    azd init --template durable-functions-quickstart-powershell-azd -e dfquickstart-powershell
    

    Este comando retira os ficheiros do projeto do repositório template e inicializa o projeto numa nova pasta. O -e sinalizador define um nome para o ambiente atual. Em azd, o ambiente mantém um contexto de implementação único para a sua aplicação, e pode definir mais do que um. O nome do ambiente também é usado no nome do grupo de recursos que crias no Azure.

  2. Muda para o diretório do projeto e depois navega até à src pasta da app:

    cd durable-functions-quickstart-powershell-azd/src
    

Provisionar recursos do Azure

Este projeto utiliza o azd provision comando para criar os recursos Azure necessários, incluindo uma nova aplicação de funções num plano Flex Consumption, um Agendador de Tarefas Durável e um hub de tarefas.

Sugestão

O projeto inclui um conjunto de ficheiros de Bicep (na pasta infra) que o azd utiliza para criar uma implementação segura num plano de consumo Flex que segue as melhores práticas.

  1. Volte à pasta raiz do projeto (a pasta que contém o azure.yaml ficheiro):

    cd ..
    
  1. Certifica-te de que ainda estás na pasta raiz do projeto (a pasta que contém o azure.yaml ficheiro).
  1. Execute este comando para autenticar com a sua conta Azure:

    azd auth login
    
  2. Execute este comando a partir da pasta raiz do projeto para criar azd os recursos Azure necessários:

    azd provision
    

    A pasta raiz contém o arquivo de azure.yaml definição exigido pelo azd.

  3. Quando solicitado, forneça estes parâmetros de implementação obrigatórios:

    Parâmetro Description
    Subscrição do Azure Subscrição na qual os seus recursos são criados. Se a sua conta tiver mais do que um inquilino, deve primeiro escolher o seu inquilino.
    Localização do Azure Região do Azure na qual criar o grupo de recursos que contém os novos recursos do Azure. Apenas as regiões que atualmente suportam o plano Flex Consumption são mostradas.
    vnetEnabled Se deve ser implementado numa rede virtual. Para este quickstart, selecione falso.

    O azd provision comando usa as tuas respostas a estes prompts com os ficheiros de configuração do Bicep para criar e configurar estes recursos Azure necessários:

    • Plano de Consumo Flexível e aplicação de função
    • Armazenamento do Azure (obrigatório) e Application Insights (recomendado)
    • Agendador de Tarefas Durável e Centro de Tarefas
    • Políticas e funções de acesso para a sua conta
    • Ligações serviço-a-serviço usando identidades geridas (em vez de cadeias de ligação armazenadas)

    Depois que o comando for concluído com êxito, você verá links para os recursos criados.

    O provisionamento também executa um script pós-provisionamento que gera o ficheiro local.settings.json na pasta da sua aplicação. Este ficheiro contém as definições de ligação do endpoint implementado do Durable Task Scheduler, de que necessita para executar o projeto localmente.

Iniciar Azurite

Para executar o projeto localmente, o runtime das Funções precisa de um emulador de armazenamento local. A "AzureWebJobsStorage": "UseDevelopmentStorage=true" definição no ficheiro local.settings.json direciona o runtime para usar o Azurite para este propósito.

Numa nova janela de terminal, execute este comando para iniciar Azurite:

azurite --skipApiVersionCheck --location ~/azurite-data

Mantém o Azurite em execução nesta janela do terminal enquanto testas localmente.

Executar no seu ambiente local

  1. No seu terminal original, vá à fanoutfanin pasta da aplicação e inicie o anfitrião Functions:

    cd fanoutfanin
    func start
    

    Quando o host de Funções inicia na sua pasta de projeto local, ele escreve na saída do terminal os endpoints locais das suas funções HTTP disparadas por URLs.

    Note

    Como a autorização da chave de acesso não é aplicada quando está a correr localmente, não precisa de uma chave de acesso para chamar a sua função.

  2. No seu navegador, faça um pedido GET ao endpoint que inicie a orquestração:

    http://localhost:7071/api/FetchOrchestration_HttpStart

    Este pedido inicia uma nova instância de orquestração. A orquestração espalha-se por várias atividades para obter os títulos dos artigos do Microsoft Learn em paralelo. Quando as atividades terminam, a orquestração é reentrada e devolve os títulos como uma cadeia formatada.

  1. No seu terminal original, vá à src pasta da app, crie e ative um ambiente virtual, instale dependências e inicie o host Functions:

    cd src
    

    A forma como cria e ativa o seu ambiente virtual (chamado .venv) depende do seu terminal:

    python3 -m venv .venv
    source .venv/bin/activate
    pip install -r requirements.txt
    func start
    

    Quando o host de Funções inicia na sua pasta de projeto local, ele escreve na saída do terminal os endpoints locais das suas funções HTTP disparadas por URLs.

    Note

    Como a autorização da chave de acesso não é aplicada quando está a correr localmente, não precisa de uma chave de acesso para chamar a sua função.

  2. No seu navegador, faça um pedido GET ao endpoint HTTP start:

    http://localhost:7071/api/orchestrators/fetch_orchestration

    Este pedido inicia uma nova instância de orquestração. A orquestração espalha-se por várias atividades para obter os títulos dos artigos do Microsoft Learn em paralelo. Quando as atividades terminam, a orquestração é reentrada e devolve os títulos como uma cadeia formatada.

  1. No teu terminal original, vai à src pasta da app, instala dependências, constrói o projeto e inicia o host de Funções:

    cd src
    npm install
    npm run build
    func start
    

    Quando o host de Funções inicia na sua pasta de projeto local, ele escreve na saída do terminal os endpoints locais das suas funções HTTP disparadas por URLs.

    Note

    Como a autorização da chave de acesso não é aplicada quando está a correr localmente, não precisa de uma chave de acesso para chamar a sua função.

  2. No seu navegador, faça um pedido GET ao endpoint HTTP start:

    http://localhost:7071/api/orchestrators/fetchOrchestration

    Este pedido inicia uma nova instância de orquestração. A orquestração espalha-se por várias atividades para obter os títulos dos artigos do Microsoft Learn em paralelo. Quando as atividades terminam, a orquestração é reentrada e devolve os títulos como uma cadeia formatada.

  1. No teu terminal original, constrói o projeto e depois inicia o host Functions a partir da pasta de saída da build:

    mvn clean package
    cd target/azure-functions/durable-functions-quickstart
    func start
    

    Quando o host de Funções inicia na sua pasta de projeto local, ele escreve na saída do terminal os endpoints locais das suas funções HTTP disparadas por URLs.

    Note

    Como a autorização da chave de acesso não é aplicada quando está a correr localmente, não precisa de uma chave de acesso para chamar a sua função.

  2. No seu navegador, faça um pedido GET ao endpoint que inicie a orquestração:

    http://localhost:7071/api/FetchOrchestration_HttpStart

    Este pedido inicia uma nova instância de orquestração. A orquestração espalha-se por várias atividades para obter os títulos dos artigos do Microsoft Learn em paralelo. Quando as atividades terminam, a orquestração é reentrada e devolve os títulos como uma cadeia formatada.

  1. No teu terminal original, vai à src pasta da app, instala dependências e inicia o host de Funções:

    cd src
    npm install
    func start
    

    Quando o host de Funções inicia na sua pasta de projeto local, ele escreve na saída do terminal os endpoints locais das suas funções HTTP disparadas por URLs.

    Note

    Como a autorização da chave de acesso não é aplicada quando está a correr localmente, não precisa de uma chave de acesso para chamar a sua função.

  2. No seu navegador, faça um pedido GET ao endpoint que inicie a orquestração:

    http://localhost:7071/api/FetchOrchestration_HttpStart

    Este pedido inicia uma nova instância de orquestração. A orquestração espalha-se por várias atividades para obter os títulos dos artigos do Microsoft Learn em paralelo. Quando as atividades terminam, a orquestração é reentrada e devolve os títulos como uma cadeia formatada.

  1. No seu terminal original, vá à src pasta da aplicação e inicie o anfitrião Functions:

    cd src
    func start
    

    Quando o host de Funções inicia na sua pasta de projeto local, ele escreve na saída do terminal os endpoints locais das suas funções HTTP disparadas por URLs.

    Note

    Como a autorização da chave de acesso não é aplicada quando está a correr localmente, não precisa de uma chave de acesso para chamar a sua função.

  2. No seu navegador, faça um pedido GET ao endpoint que inicie a orquestração:

    http://localhost:7071/api/FetchOrchestration_HttpStart

    Este pedido inicia uma nova instância de orquestração. A orquestração espalha-se por várias atividades para obter os títulos dos artigos do Microsoft Learn em paralelo. Quando as atividades terminam, a orquestração é reentrada e devolve os títulos como uma cadeia formatada.

  1. O endpoint HTTP devolve uma resposta JSON com vários URLs. O statusQueryGetUri endpoint fornece o estado da orquestração.

  2. Copie o statusQueryGetUri valor e cole no seu navegador ou na ferramenta de teste HTTP para verificar o estado da orquestração. Quando a orquestração termina, vê os títulos dos artigos buscados na resposta.

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

  1. Execute deactivate para desligar o ambiente virtual.

Rever o código (opcional)

Pode rever o código que implementa o padrão fan-out/fan-in:

As atividades de obtenção do título são acompanhadas através de uma lista dinâmica de tarefas. A linha await Task.WhenAll(parallelTasks); espera que todas as atividades chamadas, que correm simultaneamente, sejam concluídas. Quando terminado, todas as saídas são agregadas como uma cadeia formatada.

[Function(nameof(FetchOrchestration))]
public static async Task<string> RunOrchestrator(
    [OrchestrationTrigger] TaskOrchestrationContext context)
{
    ILogger logger = context.CreateReplaySafeLogger(nameof(FetchOrchestration));
    logger.LogInformation("Fetching data.");
    var parallelTasks = new List<Task<string>>();
    
    // List of URLs to fetch titles from
    var urls = new List<string>
    {
        "https://learn.microsoft.com/azure/azure-functions/durable/durable-functions-overview",
        "https://learn.microsoft.com/azure/azure-functions/durable/durable-task-scheduler/durable-task-scheduler",
        "https://learn.microsoft.com/azure/azure-functions/functions-scenarios",
        "https://learn.microsoft.com/azure/azure-functions/functions-create-ai-enabled-apps",
    };

    // Run fetching tasks in parallel
    foreach (var url in urls)
    {
        Task<string> task = context.CallActivityAsync<string>(nameof(FetchTitleAsync), url);
        parallelTasks.Add(task);
    }
    
    // Wait for all the parallel tasks to complete before continuing
    await Task.WhenAll(parallelTasks);
   
    // Return fetched titles as a formatted string
    return string.Join("; ", parallelTasks.Select(t => t.Result));
}

Você pode revisar o projeto de modelo completo aqui.

As atividades de obtenção do título são acompanhadas através de uma lista dinâmica de tarefas. A linha yield context.task_all(tasks) espera que todas as atividades chamadas, que correm simultaneamente, sejam concluídas. Quando terminado, todas as saídas são agregadas como uma cadeia formatada.

    # List of URLs to fetch titles from
    urls = [
        "https://learn.microsoft.com/azure/azure-functions/durable/durable-functions-overview",
        "https://learn.microsoft.com/azure/azure-functions/durable/durable-task-scheduler/durable-task-scheduler",
        "https://learn.microsoft.com/azure/azure-functions/functions-scenarios",
        "https://learn.microsoft.com/azure/azure-functions/functions-create-ai-enabled-apps",
    ]
    
    # Run fetching tasks in parallel
    tasks = []
    for url in urls:
        task = context.call_activity("fetch_title", url)
        tasks.append(task)
    
    # Wait for all the parallel tasks to complete before continuing
    results = yield context.task_all(tasks)
    
    # Return fetched titles as a formatted string
    return "; ".join(results)


@myApp.activity_trigger(input_name="url")
async def fetch_title(url: str):
    """Activity function that fetches the title from a URL."""
    logger = logging.getLogger("FetchTitle")
    logger.info(f"Fetching from url {url}.")
    
    try:
        async with ClientSession() as session:

Você pode revisar o projeto de modelo completo aqui.

As atividades de obtenção do título são acompanhadas através de uma lista dinâmica de tarefas. A linha yield context.df.Task.all(parallelTasks) espera que todas as atividades chamadas, que correm simultaneamente, sejam concluídas. Quando terminado, todas as saídas são agregadas como uma cadeia formatada.

    const urls = [
        "https://learn.microsoft.com/azure/azure-functions/durable/durable-functions-overview",
        "https://learn.microsoft.com/azure/azure-functions/durable/durable-task-scheduler/durable-task-scheduler",
        "https://learn.microsoft.com/azure/azure-functions/functions-scenarios",
        "https://learn.microsoft.com/azure/azure-functions/functions-create-ai-enabled-apps",
    ];

    // Run fetching tasks in parallel
    const parallelTasks = [];
    for (const url of urls) {
        const task = context.df.callActivity(fetchTitleActivityName, url);
        parallelTasks.push(task);
    }

    // Wait for all the parallel tasks to complete before continuing
    const results: string[] = yield context.df.Task.all(parallelTasks);

    // Return fetched titles as a formatted string
    return results.join("; ");
};
df.app.orchestration("fetchOrchestration", fetchOrchestration);

const fetchTitleAsync: ActivityHandler = async function (
    url: string,
    context: InvocationContext

Você pode revisar o projeto de modelo completo aqui.

As atividades de obtenção do título são acompanhadas através de uma lista dinâmica de tarefas. A linha ctx.allOf(parallelTasks).await() espera que todas as atividades chamadas, que correm simultaneamente, sejam concluídas. Quando terminado, todas as saídas são agregadas como uma cadeia formatada.

@FunctionName("FetchOrchestration")
public String runOrchestrator(
        @DurableOrchestrationTrigger(name = "taskOrchestrationContext") TaskOrchestrationContext ctx) {

    List<String> urls = List.of(
        "https://learn.microsoft.com/azure/azure-functions/durable/durable-functions-overview",
        "https://learn.microsoft.com/azure/azure-functions/durable/durable-task-scheduler/durable-task-scheduler",
        "https://learn.microsoft.com/azure/azure-functions/functions-scenarios",
        "https://learn.microsoft.com/azure/azure-functions/functions-create-ai-enabled-apps"
    );

    // Fan out: run fetching tasks in parallel
    List<Task<String>> parallelTasks = urls.stream()
        .map(url -> ctx.callActivity("FetchTitle", url, String.class))
        .collect(Collectors.toList());

    // Fan in: wait for all parallel tasks to complete
    List<String> results = ctx.allOf(parallelTasks).await();

    // Return fetched titles as a formatted string
    return String.join("; ", results);
}

Você pode revisar o projeto de modelo completo aqui.

As atividades de obtenção do título são acompanhadas através de uma lista dinâmica de tarefas. A linha yield context.df.Task.all(parallelTasks) espera que todas as atividades chamadas, que correm simultaneamente, sejam concluídas. Quando terminado, todas as saídas são agregadas como uma cadeia formatada.

df.app.orchestration('fetchOrchestration', function* (context) {
    context.log("Fetching data.");

    const urls = [
        "https://learn.microsoft.com/azure/azure-functions/durable/durable-functions-overview",
        "https://learn.microsoft.com/azure/azure-functions/durable/durable-task-scheduler/durable-task-scheduler",
        "https://learn.microsoft.com/azure/azure-functions/functions-scenarios",
        "https://learn.microsoft.com/azure/azure-functions/functions-create-ai-enabled-apps",
    ];

    // Fan out: run fetching tasks in parallel
    const parallelTasks = urls.map(url => context.df.callActivity(activityName, url));

    // Fan in: wait for all parallel tasks to complete
    const results = yield context.df.Task.all(parallelTasks);

    // Return fetched titles as a formatted string
    return results.join("; ");
});

Você pode revisar o projeto de modelo completo aqui.

As atividades de obtenção do título são acompanhadas através de uma lista dinâmica de tarefas. A linha Wait-ActivityFunction -Task $parallelTasks espera que todas as atividades chamadas, que correm simultaneamente, sejam concluídas. Quando terminado, todas as saídas são agregadas como uma cadeia formatada.

param($Context)

$urls = @(
    "https://learn.microsoft.com/azure/azure-functions/durable/durable-functions-overview",
    "https://learn.microsoft.com/azure/azure-functions/durable/durable-task-scheduler/durable-task-scheduler",
    "https://learn.microsoft.com/azure/azure-functions/functions-scenarios",
    "https://learn.microsoft.com/azure/azure-functions/functions-create-ai-enabled-apps"
)

# Fan out: run fetching tasks in parallel
$parallelTasks = @()
foreach ($url in $urls) {
    $parallelTasks += Invoke-DurableActivity -FunctionName 'FetchTitle' -Input $url -NoWait
}

# Fan in: wait for all parallel tasks to complete
$results = Wait-ActivityFunction -Task $parallelTasks

# Return fetched titles as a formatted string
$output = $results -join "; "
$output

Você pode revisar o projeto de modelo completo aqui.

Depois de verificares as tuas funções localmente, é altura de as implementares no Azure.

Publicar no Azure

Execute este comando a partir da pasta raiz do projeto para implementar o seu projeto de código na aplicação de funções no Azure:

azd deploy

O azd deploy comando empacota e distribui o seu código na aplicação de funções criada durante o provisionamento. Depois de o comando ser concluído, a aplicação inicia e executa-se no pacote implementado.

Invoque a função no Azure

Agora podes invocar o teu endpoint de orquestração no Azure fazendo um pedido HTTP para o seu URL. Quando suas funções são executadas no Azure, a autorização de chave de acesso é imposta e você deve fornecer uma chave de acesso de função com sua solicitação.

Podes usar as Core Tools para obter o endpoint URL do trigger HTTP que inicia a orquestração no Azure.

  1. No seu terminal local ou linha de comandos, execute estes comandos para obter os valores do URL do ponto final:

    APP_NAME=$(azd env get-value AZURE_FUNCTION_NAME)
    func azure functionapp list-functions $APP_NAME --show-keys
    

    O azd env get-value comando obtém o nome do aplicativo de função a partir do ambiente local. Quando utiliza a opção --show-keys com func azure functionapp list-functions, o valor devolvido por Invoke URL: para cada endpoint inclui todas as chaves de acesso necessárias ao nível da função.

  2. Usa um navegador ou uma ferramenta de teste HTTP para fazer um pedido GET ao endpoint inicial HTTP para iniciar a orquestração na tua aplicação de funções a correr no Azure.

Redistribua o teu código

Executa azd deploy tantas vezes quanto precisares para implementar atualizações de código na tua aplicação de funções. Se precisares de atualizar os recursos do Azure, executa azd provision novamente.

Note

O pacote de implementação mais recente sobrescreve sempre ficheiros de código implementados.

Suas respostas iniciais a azd prompts e quaisquer variáveis de ambiente geradas por azd são armazenadas localmente em seu ambiente nomeado. Usa o comando azd env get-values para rever todas as variáveis do teu ambiente que usaste ao criar Azure recursos.

Limpeza de recursos

Quando terminar de trabalhar com a sua function app e recursos relacionados, use este comando para eliminar a function app e os seus recursos relacionados do Azure e evitar quaisquer custos adicionais:

azd down --no-prompt

Note

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

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