Solucionar problemas comuns do SDK de Tarefas Duráveis

Este artigo ajuda você a diagnosticar e corrigir problemas comuns ao criar aplicativos com os SDKs de Tarefas Duráveis portáteis. Encontre seu cenário na lista a seguir e siga as etapas vinculadas para diagnosticar e resolver o problema.

Cenários comuns

Conexão e configuração

Orquestrações

Atividades

gRPC

Log e diagnóstico

Específico do idioma

Esses SDKs se conectam ao Durable Task Scheduler back-end e são executados em qualquer plataforma de hospedagem, incluindo Aplicativos de Contêiner do Azure, Kubernetes e VMs.

Observação

Este guia aborda os SDKs de Tarefas Duráveis portáteis. Para problemas específicos do serviço Agendador de Tarefas Duráveis, consulte Solucionar problemas do Agendador de Tarefas Duráveis. Para problemas específicos da extensão Durable Functions, consulte Durable Functions guia de solução de problemas.

Dica

O painel de monitoramento do Agendador de Tarefas Duráveis é útil para inspecionar o status da orquestração, exibir o histórico de execução e identificar falhas. Use-o junto com este guia para acelerar a solução de problemas.

Encontrar seu problema

Mensagem de erro ou sintoma Seção
connection refused ou failed to connect na inicialização O emulador não está em execução ou não pode ser acessado
Erros de autenticação ou erros de análise de cadeia de conexão na inicialização O formato da cadeia de conexão está incorreto
O trabalhador se conecta, mas as orquestrações não são iniciadas O hub de tarefas não existe
401 Unauthorized ou erros de identidade/função no Azure falhas de autenticação baseada em identidade no Azure
Orquestração presa em "Pendente" A orquestração está presa no estado "Pendente"
Orquestração presa em "Em execução" A orquestração está presa no estado "Em execução"
Falhas de reprodução, loops infinitos ou comportamento inesperado Código do orquestrador não determinístico
Problemas de desajuste de tipo ou de serialização JSON Erros de serialização e desserialização
activity not found Atividade não encontrada
RESOURCE_EXHAUSTED ou message too large Limite de tamanho da mensagem gRPC excedido
CANCELLED: Cancelled on client durante o desligamento Erros relacionados ao cancelamento de fluxo durante o desligamento
CS0419 / VSTHRD105 avisos quebram a compilação Avisos do gerador de código-fonte quebram compilações (C#)
OrchestratorBlockedException (Java) OrchestratorBlockedException (Java)
Erro inútil ao usar retry_policy (Python) A política de repetição exige max_retry_interval (Python)

Problemas de conexão e configuração

O emulador não está em execução ou não pode ser acessado

Se o aplicativo falhar na inicialização com um erro de conexão como "conexão recusada" ou "falha ao se conectar", verifique se o emulador do Agendador de Tarefas Duráveis está em execução e acessível.

  1. Verifique se o contêiner do Docker do emulador está em execução:

    docker ps | grep durabletask
    
  2. Verifique se os mapeamentos de porta estão corretos. O emulador expõe duas portas:

    • 8080 — endpoint gRPC (usado pela sua aplicação)
    • 8082 — Interface do usuário do dashboard

    Se você estiver usando um mapeamento de porta personalizado, atualize o cadeia de conexão para corresponder à porta de host mapeada para a porta de contêiner 8080.

  3. Testar a conectividade com o endpoint gRPC:

    curl -v http://localhost:8080
    

    Uma recusa de conexão indica que o contêiner não está em execução ou que o mapeamento de porta está incorreto.

O formato da cadeia de conexão está incorreto

Erros de cadeia de conexão são uma causa comum de falhas de inicialização. Verifique se o cadeia de conexão corresponde ao formato esperado.

Desenvolvimento local (emulador):

Endpoint=http://localhost:8080;Authentication=None

Azure (identidade gerenciada):

Endpoint=https://<scheduler-name>.durabletask.io;Authentication=ManagedIdentity

Azure (identidade gerenciada atribuída pelo usuário):

Endpoint=https://<scheduler-name>.durabletask.io;Authentication=ManagedIdentity;ClientID=<client-id>

Erros comuns:

  • Usando https para o emulador local (o emulador usa http)
  • Usar http para endpoints Azure (Azure requer https)
  • Omitindo o Authentication parâmetro
  • Usando a porta do painel de controle (8082) em vez da porta gRPC (8080)

Falha na conexão do cliente ou do trabalhador

Verifique se o seu cliente e o worker estão configurados com a string de conexão e o nome do hub de tarefas corretos.

using Microsoft.DurableTask.Client.AzureManaged;
using Microsoft.DurableTask.Worker.AzureManaged;

var connectionString = "Endpoint=http://localhost:8080;Authentication=None";

var builder = Host.CreateApplicationBuilder(args);

builder.Services.AddDurableTaskWorker()
    .AddTasks(registry =>
    {
        registry.AddOrchestrator<MyOrchestrator>();
        registry.AddActivity<MyActivity>();
    })
    .UseDurableTaskScheduler(connectionString);

builder.Services.AddDurableTaskClient()
    .UseDurableTaskScheduler(connectionString);

O hub de tarefas não existe

Se suas orquestrações não iniciarem ou se o trabalhador se conectar, mas não processar o trabalho, o hub de tarefas pode não existir no agendador. O emulador normalmente cria hubs de tarefas usando automaticamente a variável de DTS_TASK_HUB_NAMES ambiente.

Verifique se o emulador foi iniciado com o nome correto do hub de tarefas:

docker run -d -p 8080:8080 -p 8082:8082 \
  -e DTS_TASK_HUB_NAMES="my-taskhub" \
  mcr.microsoft.com/dts/dts-emulator:latest

Para agendadores hospedados Azure, crie o hub de tarefas usando o CLI do Azure:

az durabletask taskhub create \
  --resource-group <resource-group> \
  --scheduler-name <scheduler-name> \
  --name <taskhub-name>

Falhas de autenticação baseadas em identidade no Azure

Se o aplicativo executar localmente, mas falhar quando implantado no Azure, o problema provavelmente está relacionado à autenticação.

  1. Verifique se a identidade gerenciada está atribuída ao seu aplicativo (atribuída pelo sistema ou atribuída pelo usuário).
  2. Verifique se a identidade possui a função Contribuidor de Dados de Tarefas Duráveis no recurso do agendador ou no hub de tarefas específico.
  3. Verifique se o cadeia de conexão usa o valor Authentication correto (ManagedIdentity). Em Python, passe uma instância de DefaultAzureCredential() como o parâmetro token_credential em vez de usar uma cadeia de conexão.
  4. Para identidades atribuídas pelo usuário, verifique se o ClientID na cadeia de conexão corresponde à ID do cliente da identidade.

Para obter instruções detalhadas, consulte Configurar a identidade gerenciada para o Agendador de Tarefas Duráveis.

Problemas de orquestração

A orquestração está presa no estado "Pendente"

Uma orquestração com status “Pendente” indica que ela foi agendada, mas nenhum funcionário a selecionou. Verifique os seguintes itens:

  • O trabalho está em execução. Certifique-se de que seu processo de trabalho esteja em execução e conectado ao mesmo hub de tarefas onde a orquestração foi agendada.
  • O nome do hub de tarefas corresponde. Verifique se o trabalhador e o cliente fazem referência ao mesmo hub de tarefas. Uma incompatibilidade faz com que o trabalhador consulte um hub de tarefas diferente.
  • Orchestrator está registrado. A função ou classe do orquestrador referenciada durante o agendamento deve ser registrada com o trabalhador.

Verifique se a classe do orquestrador está registrada no trabalhador durante a inicialização. Se você usar geradores de origem ([DurableTask] atributo), o registro será automático. Caso contrário, registre-se manualmente:

builder.Services.AddDurableTaskWorker()
    .AddTasks(registry =>
    {
        registry.AddOrchestrator<MyOrchestrator>();
        registry.AddActivity<MyActivity>();
    })
    .UseDurableTaskScheduler(connectionString);

A orquestração está presa no estado "Em execução"

Uma orquestração presa em “Em execução” normalmente significa que está aguardando uma tarefa que não foi concluída. Para diagnosticar, abra o painel do agendador de tarefas duráveis e inspecione o histórico de execução da orquestração. Procure o último evento concluído — o próximo evento na sequência é o que está bloqueando o progresso.

Causas comuns:

  • Atividade não registrada. A orquestração chama um nome de atividade que não está registrado no trabalhador. O painel exibe um evento TaskScheduled sem um TaskCompleted correspondente. Verifique se o nome da atividade corresponde entre o código do orquestrador e o registro de trabalhador (consulte Atividade não encontrada).
  • Aguardando um evento externo. A orquestração chama waitForExternalEvent e o evento ainda não foi acionado. O painel mostra que um EventRaised evento é esperado, mas ausente. Verifique o nome do evento e se o remetente está apontando para a ID da instância de orquestração correta.
  • Aguardando um temporizador durável. A orquestração cria um temporizador que ainda não expirou. O painel mostra um evento TimerCreated. Aguarde até que o temporizador seja acionado ou verifique se a duração do temporizador é maior do que o esperado.
  • A atividade gera uma exceção não tratada. O painel mostra um evento TaskFailed. Verifique os detalhes da falha para a mensagem de exceção e o rastreamento de pilha.

Código do orquestrador não determinístico

O código do orquestrador deve ser determinístico. O código não determinístico causa falhas de reprodução que resultam em comportamento inesperado, loops infinitos ou erros. Não use tempo atual, números aleatórios, GUIDs ou E/S (como chamadas HTTP) diretamente no código do orquestrador. Use as alternativas fornecidas pelo contexto ou delegue para atividades.

// ❌ Wrong - non-deterministic
var now = DateTime.UtcNow;
var id = Guid.NewGuid();
var data = await httpClient.GetAsync("https://example.com/api");

// ✅ Correct - deterministic
var now = context.CurrentUtcDateTime;
var id = context.NewGuid();
var data = await context.CallActivityAsync<string>("FetchData");

Erros de serialização e desserialização

Erros de serialização ocorrem quando os tipos usados para entradas, saídas ou resultados de atividades de orquestração não correspondem entre o chamador e o chamado. Esses erros podem aparecer como valores null inesperados, JsonException ou falhas na conversão de tipos no histórico de orquestração.

Como diagnosticar:

  1. Abra o painel do Agendador de Tarefas Duráveis e inspecione o histórico de orquestração. Observe os campos Input e Result para atividades que falharam.
  2. Verifique se o tipo esperado pelo orquestrador corresponde ao tipo retornado pela atividade. Por exemplo, se a atividade retornar um string, mas o orquestrador aguardar um int, isso significará falha na desserialização.
  3. Verifique se há tipos não serializáveis. Tipos personalizados que não podem ser serializados para JSON (por exemplo, tipos com referências circulares ou nenhum construtor padrão) falham silenciosamente ou geram exceções.

Problema conhecido (Java): Passar um String diretamente para uma atividade pode resultar em strings com aspas duplas (por exemplo, "\"hello\"" em vez de "hello"). Esse comportamento é um problema conhecido. Converta o resultado explicitamente ou use objetos wrapper.

Dica

Use tipos de dados simples (cadeias de caracteres, números, matrizes e objetos sem formatação ou POJOs/POCOs/dataclasses) para entradas e saídas de orquestração e atividade. Evite tipos complexos com lógica de serialização personalizada.

Problemas de atividade

Atividade não encontrada

Se uma orquestração falhar com um erro “atividade não encontrada”, o nome da atividade registrado com o trabalhador não corresponde ao nome usado no código de orquestração.

Em .NET, as atividades podem ser registradas por nome de classe ou usando o atributo [DurableTask] com geradores de origem. Verifique se a classe de atividade está incluída no registro de trabalho:

builder.Services.AddDurableTaskWorker()
    .AddTasks(registry =>
    {
        registry.AddActivity<SayHello>();
    })
    .UseDurableTaskScheduler(connectionString);

Ao chamar a atividade de um orquestrador, use o nome da classe:

string result = await context.CallActivityAsync<string>(nameof(SayHello), "Tokyo");

Gestão de Falhas em Atividades

Quando uma atividade gera uma exceção, o orquestrador recebe um TaskFailedException (ou equivalente na linguagem). Pegue essa exceção e inspecione os detalhes do erro interno para localizar a causa raiz. Em C#, use ex.FailureDetails para acessar o tipo de erro e a mensagem e IsCausedBy<T>() verificar se há tipos de exceção específicos.

Para obter exemplos detalhados de política de tratamento de erros e repetição em cada idioma, consulte Tratamento de erros e novas tentativas.

Problemas de gRPC

Erro: Limite de tamanho da mensagem gRPC excedido

Se você vir um erro RESOURCE_EXHAUSTED ou message too large, uma entrada/saída de atividade ou de orquestração excederá o tamanho máximo padrão de mensagem gRPC de 4 MB.

Atenuações:

  • Reduza o tamanho de entradas e saídas. Armazene grandes cargas úteis em armazenamento externo, como o Armazenamento de Blobs do Azure e passe apenas referências.
  • Divida resultados de grande dispersão em lotes menores processados por meio de suborquestrações.

Erros de cancelamento de transmissão durante o desligamento

Ao parar um trabalhador você poderá ver os erros CANCELLED: Cancelled on client. Esses erros são normalmente inofensivos e ocorrem porque a transmissão gRPC entre o trabalhador e o agendador é encerrada durante o desligamento. Os SDKs .NET, Python e Java lidam com esses erros internamente.

No JavaScript, o SDK pode gerar Stream error Error: 1 CANCELLED: Cancelled on client ao chamar worker.stop(). Esse erro é um problema conhecido. Envolva a chamada de parada em um try-catch se o erro afetar sua lógica de desligamento:

try {
  await worker.stop();
} catch (error) {
  // Ignore stream cancellation errors during shutdown
  if (!error.message.includes("CANCELLED")) {
    throw error;
  }
}

Registro e diagnósticos

Configuração de log detalhado

Aumente a verbosidade do log para obter mais detalhes sobre as operações do SDK, incluindo comunicação gRPC e eventos de reprodução de orquestração.

em seu appsettings.json ou arquivo de configuração de log:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.DurableTask": "Debug"
    }
  }
}

Use registradores seguros para reprodução para evitar entradas duplicadas no log durante a reprodução da orquestração:

public override async Task<string> RunAsync(
    TaskOrchestrationContext context, string input)
{
    ILogger logger = context.CreateReplaySafeLogger<MyOrchestrator>();
    logger.LogInformation("Processing input: {Input}", input);
    // ...
}

Integração do Application Insights

Para aplicativos de produção, configure o Application Insights para coletar telemetria de seu aplicativo SDK de Tarefa Durável. A abordagem de integração depende da plataforma de hospedagem:

Plataforma de hospedagem Instruções de instalação
Aplicativos de Contêiner do Azure Monitorar logs nos Aplicativos de Contêiner do Azure com o Log Analytics
Serviço de Aplicativo do Azure Ativar a gravação de logs de diagnóstico para aplicativos no Serviço de Aplicativo do Azure
Serviço de Kubernetes do Azure Monitorar o Serviço de Kubernetes do Azure

Para obter mais informações sobre diagnóstico, consulte Diagnóstico em SDKs de Tarefas Duráveis.

Problemas específicos do idioma

C#

Os avisos do gerador de código interrompem as compilações

Se você usar <TreatWarningsAsErrors>true</TreatWarningsAsErrors> em seu projeto, os geradores de código-fonte da Tarefa Durável poderão produzir avisos (CS0419, VSTHRD105) que interrompem a compilação. Suprime estes avisos específicos:

<PropertyGroup>
  <NoWarn>$(NoWarn);CS0419;VSTHRD105</NoWarn>
</PropertyGroup>

Esse problema conhecido está sendo rastreado no GitHub e é abordado em uma versão futura.

O analisador Roslyn lança loops foreach

O analisador Roslyn de Tarefas Duráveis pode gerar um ArgumentNullException quando o código lambda do orquestrador estiver dentro de um loop foreach. Esse comportamento é um problema conhecido que não afeta o comportamento do runtime. Atualize para a versão mais recente do pacote do analisador para obter a correção.

Java

Erro de permissão negada do Gradle

No macOS ou linux, a execução ./gradlew pode falhar com um erro de "permissão negada". Corrija esse erro tornando o arquivo executável:

chmod +x gradlew

OrchestratorBlockedException

O OrchestratorBlockedException ocorre quando o código do orquestrador executa uma operação de bloqueio que o SDK detecta como potencialmente não determinística. Essa exceção é uma proteção para impedir que o código do orquestrador viole restrições de código do orquestrador.

Causas comuns:

  • Invocando uma API externa bloqueante no código do orquestrador.
  • Usando Thread.sleep() diretamente em vez de ctx.createTimer().
  • Executando E/S de arquivo ou rede no código do orquestrador.

Mova todas as operações de bloqueio ou E/S para atividades.

Python

A política de repetição exige o parâmetro max_retry_interval

Quando você configura um retry_policy no Python, omitir o parâmetro max_retry_interval produz um erro que não indica claramente a causa. Sempre especifique max_retry_interval:

from datetime import timedelta
from durabletask import task

retry_policy = task.RetryPolicy(
    max_number_of_attempts=3,
    first_retry_interval=timedelta(seconds=5),
    max_retry_interval=timedelta(minutes=1),  # Required
)

Comportamento de exceção do WhenAllTask

Quando você usa when_all para executar várias tarefas em paralelo, se uma ou mais tarefas falharem, o comportamento da exceção pode não corresponder às expectativas. Somente a primeira exceção é gerada e as exceções de tarefa restantes podem ser perdidas. Inspecione os resultados de tarefas individuais se precisar de informações de erro completas:

tasks = [ctx.call_activity(process_item, input=item) for item in items]
try:
    results = yield task.when_all(tasks)
except TaskFailedError as e:
    # Only the first failure is raised
    # Check individual tasks for comprehensive error handling
    print(f"At least one task failed: {e}")

Obtenha suporte

Para perguntas e relatórios de bugs, abra um problema no repositório GitHub para o SDK relevante. Ao relatar um bug, inclua:

  • IDs das instâncias de orquestração afetadas
  • Intervalo de tempo em UTC que mostra o problema
  • Nome do aplicativo e região de implantação (se relevante)
  • Versão do SDK e plataforma de hospedagem
  • Logs relevantes ou mensagens de erro
SDK Repositório GitHub
.NET microsoft/durabletask-dotnet
Java microsoft/durabletask-java
JavaScript microsoft/durabletask-js
Python microsoft/durabletask-python