Hubs de tarefas

Um hub de tarefas é uma representação do estado atual do aplicativo no armazenamento, incluindo todo o trabalho pendente. Enquanto um aplicativo é executado, o hub de tarefas armazena continuamente o progresso das funções de orquestração, atividade e entidade. Essa abordagem garante que o aplicativo possa retomar o processamento do ponto em que parou, caso seja reiniciado após uma interrupção temporária. Um hub de tarefas também permite que os aplicativos dimensionem os recursos de computação dinamicamente.

Este artigo explica o que um hub de tarefas armazena, como configurar e nomear hubs de tarefas, como criá-los e gerenciá-los com back-ends de armazenamento diferentes e como o processo dos hubs de tarefas funciona internamente.

Captura de tela do diagrama mostrando o aplicativo de funções e a arquitetura do hub de tarefas na Tarefa Durável.

Conceitualmente, um hub de tarefas armazena as seguintes informações:

  • Os estados de instância de todas as instâncias de orquestração e entidade.
  • As mensagens a serem processadas, incluindo:
    • Todas as mensagens de atividade que representam atividades aguardando execução.
    • Quaisquer mensagens de instância que estejam aguardando para serem entregues às instâncias.

As mensagens de atividade são sem estado e podem ser processadas em qualquer lugar. As mensagens de instância precisam ser entregues a uma instância com estado específico (orquestração ou entidade), identificada por sua ID de instância.

Internamente, cada provedor de armazenamento pode usar uma organização diferente para representar estados e mensagens de instância. Por exemplo, o provedor de Azure Storage armazena mensagens em filas Azure Storage, mas o provedor MSSQL as armazena em tabelas relacionais. Essas diferenças não importam para o design do aplicativo, mas algumas delas podem influenciar as características de desempenho. Para obter mais informações, consulte Representação no armazenamento.

Os SDKs de Tarefas Duráveis usam o Agendador de Tarefas Duráveis como o back-end para hubs de tarefas. O Agendador de Tarefas Duráveis é um serviço totalmente gerenciado que manipula o armazenamento internamente.

Nomes de hub de tarefas

Os hubs de tarefas são identificados por um nome que está em conformidade com estas regras:

  • Contém apenas caracteres alfanuméricos
  • Começa com uma letra
  • Tem um comprimento mínimo de 3 caracteres, comprimento máximo de 45 caracteres

Declare o nome do hub de tarefas no arquivo host.json , conforme mostrado no exemplo a seguir:

host.json (Funções 2.0)

{
  "version": "2.0",
  "extensions": {
    "durableTask": {
      "hubName": "MyTaskHub"
    }
  }
}

host.json (Functions 1.x)

{
  "durableTask": {
    "hubName": "MyTaskHub"
  }
}

Você também pode configurar hubs de tarefas usando as configurações do aplicativo, conforme mostrado no seguinte host.json arquivo de exemplo:

host.json (Funções 2.0)

{
  "version": "2.0",
  "extensions": {
    "durableTask": {
      "hubName": "%MyTaskHub%"
    }
  }
}

host.json (Functions 1.x)

{
  "durableTask": {
    "hubName": "%MyTaskHub%"
  }
}

O nome do hub de tarefas é definido com o valor da configuração do aplicativo MyTaskHub. O arquivo local.settings.json a seguir mostra como definir a MyTaskHub configuração como samplehubname:

{
  "IsEncrypted": false,
  "Values": {
    "MyTaskHub" : "samplehubname"
  }
}

Observação

Ao usar slots de implantação, é uma prática recomendada configurar o nome do hub de tarefas usando as configurações do aplicativo. Se você desejar garantir que um slot específico sempre use um certo hub de tarefas, use as configurações de aplicativo "slot-sticky".

Além de host.json, os nomes do hub de tarefas também podem ser configurados nos metadados de vinculação do cliente de orquestração. Essa configuração é útil quando você precisa acessar orquestrações ou entidades que residem em um aplicativo de funções separado. O seguinte código mostra como escrever uma função que usa a associação de cliente de orquestração para trabalhar com um hub de tarefas configurado como uma configuração de aplicativo:

[FunctionName("HttpStart")]
public static async Task<HttpResponseMessage> Run(
    [HttpTrigger(AuthorizationLevel.Function, methods: "post", Route = "orchestrators/{functionName}")] HttpRequestMessage req,
    [DurableClient(TaskHub = "%MyTaskHub%")] IDurableOrchestrationClient starter,
    string functionName,
    ILogger log)
{
    // Function input comes from the request content.
    object eventData = await req.Content.ReadAsAsync<object>();
    string instanceId = await starter.StartNewAsync(functionName, eventData);

    log.LogInformation($"Started orchestration with ID = '{instanceId}'.");

    return starter.CreateCheckStatusResponse(req, instanceId);
}

Observação

O exemplo anterior é para Durable Functions 2.x. Para Durable Functions 1.x, use DurableOrchestrationContext em vez de IDurableOrchestrationContext. Para obter mais informações sobre as diferenças entre as versões, consulte o artigo Durable Functions versions.

Observação

Configurar os nomes dos hubs de tarefas nos metadados de vinculação do cliente só é necessário quando você usa um aplicativo de funções para acessar orquestrações e entidades em outro aplicativo de funções. Se as funções do cliente estiverem definidas no mesmo aplicativo de funções que as orquestrações e entidades, evite especificar nomes de hubs de tarefas nos metadados de vinculação. Por padrão, todas as associações de cliente obtêm os metadados do hub de tarefas das configurações do host.json.

Se não for especificado, um nome de hub de tarefas padrão será usado conforme mostrado na tabela a seguir:

Versão de extensão durável Nome padrão do hub de tarefas
2.x Quando implantado em Azure, o nome do hub de tarefas é derivado do nome do aplicativo function. Ao executar fora de Azure, o nome do hub de tarefas padrão é TestHubName.
1.x O nome padrão do hub de tarefas para todos os ambientes é DurableFunctionsHub.

Para obter mais informações sobre as diferenças entre as versões de extensão, consulte o artigo Versões do Durable Functions.

Usar vários aplicativos com hubs de tarefas separados

Cada aplicativo que compartilha um back-end deve se conectar ao seu próprio hub de tarefas para evitar conflitos. Se vários aplicativos usam o mesmo hub de tarefas, eles competem por mensagens, o que pode resultar em um comportamento indefinido, incluindo orquestrações ficando inesperadamente paralisadas. Um único back-end pode conter vários hubs de tarefas; configurar cada aplicativo com o seu próprio.

Esse requisito se aplica a todos os back-ends de armazenamento. Para provedores de armazenamento BYO (Armazenamento do Azure, Netherite, MSSQL), configure cada aplicativo de funções com um nome de hub de tarefas separado. Este requisito também se aplica aos slots de preparação: configure cada slot de preparação com um nome de hub de tarefas exclusivo.

Importante

Por padrão, o nome do aplicativo é usado como o nome do hub de tarefas, o que garante que o compartilhamento acidental não aconteça. Se você configurar explicitamente os nomes do hub de tarefas em host.json, verifique se os nomes são exclusivos. A única exceção é se você implantar cópias do mesmo aplicativo em várias regiões para recuperação de desastre. Nesse caso, use o mesmo hub de tarefas para as cópias.

O diagrama a seguir ilustra um hub de tarefas por aplicativo de função em contas compartilhadas e dedicadas de Azure Storage.

Captura de tela de diagrama mostrando um hub de tarefas por aplicativo de funções em contas de Armazenamento do Azure compartilhadas e dedicadas.

Gerenciamento do hub de tarefas do Agendador de Tarefas Durável

Esta seção aborda como criar e gerenciar hubs de tarefas ao usar o back-end do Agendador de Tarefas Duráveis. Crie os recursos do agendador e do hub de tarefas explicitamente antes que seu aplicativo os use.

Criar um agendador e um hub de tarefas

Crie um agendador e um hub de tarefas usando o portal Azure, Azure CLI, Azure Resource Manager (ARM) ou Bicep.

  1. No portal do Azure, pesquise o Agendador de Tarefas Duráveis e selecione-o nos resultados.

  2. Selecione Criar para abrir o painel de criação do agendador.

  3. Preencha os campos na guia Noções básicas , incluindo o grupo de recursos, o nome do agendador, a região e a SKU. Selecione Examinar + criar.

  4. Depois da aprovação na validação, selecione Criar. A implantação leva até 15 minutos.

  5. Depois que o agendador for criado, acesse o recurso do agendador. Na página Visão geral , crie um novo hub de tarefas.

Importante

A 0.0.0.0/0 lista de permissões de IP permite o acesso de qualquer endereço IP. Para implantações de produção, restrinja isso apenas aos intervalos de IP necessários.

Os exemplos anteriores usam o SKU Dedicado. O Agendador de Tarefas Duráveis também oferece um SKU de Consumo. Para obter mais informações sobre como gerenciar recursos do Agendador de Tarefas Duráveis, consulte Desenvolver com o Agendador de Tarefas Duráveis.

Configurar a autenticação baseada em identidade

O Agendador de Tarefas Duráveis dá suporte apenas à autenticação de identidade gerenciada. Ele não dá suporte a cadeias de conexão com chaves de armazenamento. Atribua a função RBAC (controle de acesso baseado em função) apropriada a uma identidade gerenciada e configure seu aplicativo para usar essa identidade.

As seguintes funções estão disponíveis:

Função Descrição
Colaborador de Dados de Tarefa Durável Acesso completo a dados. Superconjunto de todas as outras funções.
Trabalho de Tarefa Durável Interaja com o agendador para processar orquestrações, atividades e entidades.
Leitor de dados de tarefa durável Acesso somente leitura aos dados de orquestração e de entidades.

Observação

A maioria dos aplicativos requer a função Colaborador de Dados de Tarefas Duráveis.

Use identidades gerenciadas atribuídas pelo usuário quando possível porque elas não estão vinculadas ao ciclo de vida do aplicativo e você pode reutilizá-las depois que o aplicativo for removido.

  1. Acesse o recurso do agendador ou do hub de tarefas no portal do Azure.

  2. Selecione Controle de acesso (IAM) no menu à esquerda.

  3. Selecione Adicionar>Adicionar atribuição de função.

  4. Pesquise e selecione Colaborador de Dados da Tarefa Durável. Selecione Próximo.

  5. Em Atribuir acesso a, selecione Identidade Gerenciada. Selecione + Selecionar membros.

  6. Selecione a identidade gerenciada atribuída pelo usuário, escolha a identidade e selecione Selecionar.

  7. Selecione Examinar + atribuir para concluir.

  8. Vá para seu aplicativo de funções e selecione Configurações>Identidade. Selecione a guia Usuário atribuído e adicione a identidade.

Depois de atribuir a identidade, adicione as seguintes variáveis de ambiente ao seu aplicativo:

Variable Valor
TASKHUB_NAME O nome do hub de tarefas.
DURABLE_TASK_SCHEDULER_CONNECTION_STRING Endpoint={scheduler endpoint};Authentication=ManagedIdentity;ClientID={client id}

Observação

Se você usar uma identidade gerenciada atribuída pelo sistema, omita o segmento ClientID do connection string: Endpoint={scheduler endpoint};Authentication=ManagedIdentity.

Para obter detalhes completos da configuração de identidade, consulte Configurar a identidade gerenciada para o Agendador de Tarefas Duráveis.

Gerenciamento do hub de tarefas do provedor de armazenamento BYO

Esta seção aborda a criação e a exclusão do hub de tarefas e a inspeção do conteúdo do hub de tarefas. Aplica-se a provedores de armazenamento auto-gerenciado (BYO - bring-your-own): Azure Storage, Netherite e MSSQL.

Criar e excluir hubs de tarefas

Um hub de tarefas vazio com todos os recursos necessários é criado automaticamente no armazenamento quando um aplicativo de funções é iniciado pela primeira vez.

Se você usar o provedor de Azure Storage, nenhuma configuração adicional será necessária. Caso contrário, siga as instruções para configurar provedores de armazenamento para garantir que o provedor de armazenamento possa configurar e acessar corretamente os recursos de armazenamento necessários para o hub de tarefas.

Observação

O hub de tarefas não é excluído automaticamente quando você para ou exclui o aplicativo de funções. Para remover esses dados, exclua manualmente o hub de tarefas, seu conteúdo ou a conta de armazenamento que contém.

Dica

Em um cenário de desenvolvimento, talvez seja necessário reiniciar de um estado limpo com frequência. Para fazer isso rapidamente, basta alterar o nome do hub de tarefas configurado. Essa alteração força a criação de um novo hub de tarefas vazio ao reiniciar o aplicativo. Os dados antigos não são excluídos nesse caso.

Inspecionar o conteúdo do hub de tarefas

Há várias maneiras comuns de inspecionar o conteúdo de um hub de tarefas:

  • Em um aplicativo de funções, o objeto cliente fornece métodos para consultar o repositório de instâncias. Para saber mais sobre quais tipos de consultas têm suporte, consulte o artigo Gerenciamento de Instâncias .
  • Da mesma forma, a API HTTP oferece solicitações REST para consultar o estado de orquestrações e entidades. Consulte a Referência de API HTTP para obter mais detalhes.
  • A ferramenta Durable Functions Monitor pode inspecionar hubs de tarefas e oferece várias opções para exibição visual.

Para alguns provedores de armazenamento, você também pode inspecionar o hub de tarefas acessando diretamente o armazenamento subjacente:

  • Se você usar o provedor de Azure Storage, os estados de instância serão armazenados na tabela Instance e na tabela History, que você pode inspecionar usando ferramentas como Azure Storage Explorer.
  • Se você usar o provedor de armazenamento MSSQL, use consultas SQL e ferramentas para inspecionar o conteúdo do hub de tarefas no banco de dados.

Itens de trabalho

As mensagens de atividade e as mensagens de instância no hub de tarefas representam o trabalho que o aplicativo precisa processar. Enquanto o aplicativo está em execução, ele busca continuamente itens de trabalho do hub de tarefas. Cada item de trabalho processa uma ou mais mensagens. Há dois tipos de itens de trabalho:

  • Itens de trabalho de atividade: executar uma função de atividade para processar uma mensagem de atividade.
  • Itens de trabalho do orquestrador: executam uma função de orquestrador ou entidade para processar uma ou mais mensagens de instância.

Os trabalhadores podem processar vários itens de trabalho ao mesmo tempo, sujeitos aos limites de simultaneidade por trabalho configurados.

Para saber mais sobre limitações de simultaneidade, confira Desempenho e escala.

Depois que um trabalho conclui um item de trabalho, ele confirma os efeitos de volta para o hub de tarefas. Esses efeitos variam de acordo com o tipo de função que foi executada:

  • Uma função de atividade concluída cria uma mensagem de instância contendo o resultado, endereçada à instância do orquestrador pai.
  • Uma função de orquestrador concluída atualiza o estado e o histórico da orquestração e pode criar novas mensagens.
  • Uma função de entidade concluída atualiza o estado da entidade e também pode criar novas mensagens de instância.

Para orquestrações, cada item de trabalho representa um episódio da execução dessa orquestração. Um episódio é uma rodada do orquestrador em execução, processando resultados disponíveis e, em seguida, pausando até que o próximo resultado chegue. Por exemplo, um episódio começa quando a orquestração começa, quando uma atividade é concluída e retorna um resultado ou quando um evento externo chega. O episódio termina quando o orquestrador termina ou chega a um ponto em que deve aguardar novas mensagens.

Exemplo de execução

Considere uma orquestração do tipo fan-out-fan-in que inicia duas atividades em paralelo e aguarda que ambas sejam concluídas:

[FunctionName("Example")]
public static async Task Run([OrchestrationTrigger] IDurableOrchestrationContext context)
{
    Task t1 = context.CallActivityAsync<int>("MyActivity", 1);
    Task t2 = context.CallActivityAsync<int>("MyActivity", 2);
    await Task.WhenAll(t1, t2);
}
using Microsoft.DurableTask;

public class Example : TaskOrchestrator<object?, object?>
{
    public override async Task<object?> RunAsync(TaskOrchestrationContext context, object? input)
    {
        Task t1 = context.CallActivityAsync("MyActivity", 1);
        Task t2 = context.CallActivityAsync("MyActivity", 2);
        await Task.WhenAll(t1, t2);
        return null;
    }
}

Depois que essa orquestração é iniciada por um cliente, o aplicativo o processa como uma sequência de itens de trabalho. Cada item de trabalho concluído atualiza o estado do hub de tarefas quando ele é confirmado. Estas são as etapas:

  1. Um cliente solicita iniciar uma nova orquestração com a ID da instância "123". Depois que o cliente concluir essa solicitação, o hub de tarefas conterá um espaço reservado para o estado de orquestração e uma mensagem de instância:

    Captura de tela do diagrama mostrando o estado do hub de tarefas após a solicitação de início da orquestração na primeira etapa.

    O rótulo ExecutionStarted é um dos muitos tipos de eventos de histórico que identificam os vários tipos de mensagens e eventos que participam do histórico de uma orquestração.

  2. Um trabalhador executa um item de trabalho do orquestrador para processar a ExecutionStarted mensagem. Ele chama a função orquestradora que inicia a execução do código de orquestração. Esse código agenda duas atividades e, em seguida, interrompe a execução quando aguarda os resultados.

    Captura de tela do diagrama mostrando o estado do hub de tarefas após a confirmação do primeiro item de trabalho do orquestrador na etapa dois.

    O estado de runtime é agora Running, e o histórico registra este primeiro episódio: o orquestrador começou, a execução começou, duas tarefas foram agendadas, e o orquestrador concluiu o episódio.

  3. Um trabalhador executa um item de trabalho de atividade para processar uma das TaskScheduled mensagens. Ele chama a função de atividade com a entrada "2". Quando a função de atividade é concluída, ela cria uma TaskCompleted mensagem que contém o resultado.

    Captura de tela do diagrama mostrando o estado do hub de tarefas após a confirmação do item de trabalho da primeira atividade na etapa três.

  4. Um trabalhador executa um item de trabalho do orquestrador para processar a TaskCompleted mensagem. Se a orquestração ainda estiver armazenada em cache na memória, ela poderá apenas retomar a execução. Caso contrário, o trabalho primeiro repete a história para recuperar o estado atual da orquestração. Em seguida, continua a orquestração, entregando o resultado da atividade. Depois de receber esse resultado, a orquestração ainda aguarda o resultado da outra atividade, portanto, ela para mais uma vez a execução.

    Captura de tela do diagrama mostrando o estado do hub de tarefas após a confirmação do segundo item de trabalho do orquestrador na etapa quatro.

    O histórico registra o segundo episódio: a tarefa concluída e o orquestrador pausado novamente.

  5. Um trabalho executa um item de trabalho de atividade para processar a mensagem TaskScheduled restante. Ele chama a função de atividade com a entrada "1".

    Captura de tela do diagrama mostrando o estado do hub de tarefas após a confirmação do item de trabalho da segunda atividade na etapa cinco.

  6. Um trabalhador executa outro item de trabalho do orquestrador para processar a TaskCompleted mensagem. Depois de receber este segundo resultado, a orquestração é concluída.

    Captura de tela do diagrama mostrando o estado do hub de tarefas após o envio do item final de trabalho do orquestrador na etapa seis.

    O estado de runtime é agora Completed, e o histórico registra o terceiro e último episódio: a segunda tarefa concluída e a execução concluída.

Observação

A agenda mostrada não é a única possível. Por exemplo, se a segunda atividade for concluída anteriormente, ambas as TaskCompleted mensagens poderão ser processadas por um único item de trabalho, resultando em apenas dois episódios em vez de três.

Representação no sistema de armazenamento

Cada provedor de armazenamento usa uma organização interna diferente para representar hubs de tarefas no armazenamento. Entender essa organização, embora não seja necessário, pode ajudar na solução de problemas ou ao tentar atender a metas de desempenho, escalabilidade ou custo.

Os SDKs de Tarefas Duráveis usam o Agendador de Tarefas Duráveis como o back-end, que gerencia o estado do hub de tarefas internamente.

Provedor de Agendador de Tarefas Duráveis

O Agendador de Tarefas Duráveis é um provedor de back-end totalmente gerenciado que armazena todo o estado do hub de tarefas internamente. Ao contrário dos provedores de armazenamento BYO (bring-your-own), você não precisa configurar nem gerenciar nenhuma infraestrutura de armazenamento subjacente. Cada recurso do agendador (Microsoft.DurableTask/schedulers) tem recursos de computação e memória dedicados e pode conter um ou mais hubs de tarefas (Microsoft.DurableTask/schedulers/taskHubs).

Como o Agendador de Tarefas Duráveis gerencia o armazenamento internamente, você não pode inspecionar diretamente os dados subjacentes. Em vez disso, use o painel Agendador de Tarefas Duráveis para monitorar e consultar instâncias de orquestração.

Para obter mais informações sobre as opções do provedor de armazenamento BYO e como elas se comparam, consulte os provedores de armazenamento Durable Functions.

provedor de armazenamento Azure

O provedor Azure Storage representa o hub de tarefas no armazenamento usando os seguintes componentes:

  • Duas tabelas de Azure armazenam os estados da instância.
  • Uma Fila do Azure armazena as mensagens de atividade.
  • Uma ou mais Filas do Azure armazenam as mensagens da instância. Cada uma dessas chamadas filas de controle representa uma partição que é atribuída a um subconjunto de todas as mensagens da instância, com base no hash da ID da instância.
  • Alguns contêineres de blobs extras são usados ​​para blobs de arrendamento ou mensagens grandes.

Por exemplo, um hub de tarefas nomeado xyz com PartitionCount = 4 contém as seguintes filas e tabelas:

Captura de tela do diagrama mostrando a organização do hub de tarefas do provedor de Armazenamento do Azure com quatro filas de controle.

As seções a seguir descrevem esses componentes e suas funções com mais detalhes.

Para obter mais informações sobre como os hubs de tarefas são representados pelo provedor Azure Storage, consulte a documentação do provedor Azure Storage.

Provedor de Armazenamento Netherite (Caminho de Aposentadoria)

O Netherite particiona todo o estado do hub de tarefas em um número especificado de partições. No armazenamento, esses recursos armazenam os dados:

  • Um Azure Storage contêiner de blob que contém todos os blobs, agrupados por partição.
  • Uma Tabela do Azure que contém métricas já publicadas sobre as partições.
  • Um namespace Azure Event Hubs para fornecer mensagens entre partições.

Por exemplo, um hub de tarefas nomeado mytaskhub com PartitionCount = 32 é representado no armazenamento da seguinte maneira:

Captura de tela do diagrama mostrando a organização de armazenamento netherite para o hub de tarefas com 32 partições.

Observação

Todo o estado do hub de tarefas é armazenado dentro do contêiner de x-storage blob. A DurableTaskPartitions tabela e o namespace dos Hubs de Eventos contêm dados redundantes: se o conteúdo for perdido, eles poderão ser recuperados automaticamente. Portanto, você não precisa configurar o namespace Azure Event Hubs para reter mensagens após o tempo de expiração padrão.

O Netherite usa um mecanismo de fornecimento de eventos, com base em um log e pontos de verificação, para representar o estado atual de uma partição. Blobs de blocos e blobs de página armazenam os dados. Você não pode ler esse formato diretamente do armazenamento, portanto, o aplicativo de funções deve estar em execução ao consultar o repositório de instâncias.

Para obter mais informações sobre hubs de tarefas para o provedor de armazenamento Netherite, consulte as informações do Hub de Tarefas para o provedor de armazenamento Netherite.

Provedor do armazenamento MSSQL

Todos os dados do hub de tarefas são armazenados em um único banco de dados relacional, usando estas tabelas:

  • As dt.Instances tabelas e as dt.History tabelas armazenam os estados da instância.
  • A dt.NewEvents tabela armazena as mensagens da instância.
  • A dt.NewTasks tabela armazena as mensagens de atividade.

Captura de tela do diagrama mostrando a organização do hub de tarefas do provedor de armazenamento MSSQL com tabelas de banco de dados.

Para permitir que vários hubs de tarefas coexistam independentemente no mesmo banco de dados, cada tabela inclui uma TaskHub coluna como parte de sua chave primária. Ao contrário dos outros dois provedores, o provedor MSSQL não tem partições.

Para obter mais informações sobre hubs de tarefas para o provedor de armazenamento MSSQL, consulte as informações do Hub de Tarefas para o provedor de armazenamento do MICROSOFT SQL (MSSQL).