Guia de solução de problemas do Durable Functions

Este artigo ajuda-o a resolver cenários comuns em aplicações Durable Functions. Encontre o seu sintoma na lista seguinte e siga os passos indicados para diagnosticar e resolver o problema.

Sintomas comuns

Para consultas de diagnóstico KQL que podem ser executadas no Application Insights, consulte Consultas KQL de Exemplo para Diagnósticos de Durable Functions.

A orquestração está presa no Pending estado

Quando inicias uma orquestração, uma mensagem de "início" é escrita numa fila interna gerida pela Extensão Durable, e o estado da orquestração é definido como "Pendente". Depois de uma instância de aplicação disponível capturar e processar com sucesso a mensagem de orquestração, o estado transita para "Em Execução" (ou para outro estado que não seja "Pendente").

Siga estes passos para diagnosticar instâncias de orquestração que permaneçam indefinidamente presas no estado "Pendente".

  1. Verifique os rastreios do Durable Task Framework para avisos ou erros para o ID de instância de orquestração afetado. Utilize a consulta de erros e avisos em Application Insights para procurar erros relacionados com a sua instância.

  2. Verifique as filas de controlo do Armazenamento do Azure para ver se a "mensagem de início" da orquestração ainda está na fila. No portal Azure, navegue até à sua conta de armazenamento, selecione Filas e procure filas com o prefixo control. Para obter contexto sobre como funcionam as filas de controlo, consulte a documentação da fila de controlo do fornecedor do Armazenamento do Azure.

  3. Muda a configuração da plataforma da tua app para 64 Bits. As orquestrações por vezes falham em iniciar porque a aplicação está a ficar sem memória. Mudar para um processo de 64 bits permite que a aplicação aloque mais memória total. Esta alteração aplica-se apenas aos planos App Service Basic, Standard, Premium e Elastic Premium. Planos Gratuitos ou de Consumo não suportam processos de 64 bits.

As orquestrações começam após um longo atraso

Normalmente, as orquestrações começam dentro de alguns segundos depois de serem agendadas. No entanto, em certos casos, as orquestrações podem demorar mais tempo a começar. Siga estes passos para resolver problemas quando as orquestrações demorarem mais do que alguns segundos a começar.

  1. Verifique se o atraso corresponde a uma limitação conhecida do fornecedor Armazenamento do Azure, como reequilíbrio de partições ou intervalos de sondagem baseados em temporizador.

  2. Verifique os registos do Durable Task Framework à procura de avisos ou erros com o ID da instância de orquestração afetada. Utilize a consulta "Trace errors and warnings" no Application Insights para procurar por erros relacionados com a sua instância.

A orquestração está presa no Running estado

Se o estado da orquestração mostrar "Em execução" por mais tempo do que o esperado, ou se parecer ter deixado de progredir, é provável que a orquestração esteja à espera de uma tarefa que não foi concluída. Por exemplo, pode estar à espera de um temporizador duradouro, de uma tarefa de atividade ou de um evento externo. Se as tarefas agendadas forem concluídas com sucesso, mas a orquestração ainda não avançar, pode haver um problema a impedir a orquestração de avançar para o passo seguinte. Orquestrações neste estado são frequentemente chamadas de "orquestrações presas".

Siga estes passos para resolver o problema de orquestrações imobilizadas:

  1. Tente reiniciar o aplicativo de função. Esta etapa pode ajudar se a orquestração ficar presa devido a um bug transitório ou deadlock na aplicação ou no código da extensão.

  2. Verifique as filas de controlo de contas do Armazenamento do Azure para ver se alguma fila está a crescer continuamente. Utilize a consulta de mensagens Armazenamento do Azure no Application Insights para identificar problemas com a retirada de mensagens de orquestração. Se o problema afetar apenas uma única fila de controlo, pode indicar um problema numa instância específica da aplicação. Nesse caso, escalar para cima ou para baixo para sair da instância de VM pouco saudável pode ajudar.

  3. Filtra os resultados da consulta de mensagens Armazenamento do Azure pelo nome da fila como ID de Partição para procurar problemas relacionados com essa partição específica da fila de controlo.

  4. Consulte a documentação sobre a versão do Durable Functions. Alterações de ruptura nas instâncias de orquestração em voo podem levar a orquestrações ficarem presas.

A orquestração demora mais do que o esperado a concluir

Processamento intensivo de dados, erros internos e recursos computacionais insuficientes podem fazer com que as orquestrações corram mais lentamente do que o normal. Siga estes passos para resolver orquestrações que demoram mais do que o esperado a concluir:

  1. Verifique os registos do Durable Task Framework em busca de avisos ou erros para o ID da instância de orquestração afetada. Utilize a consulta Trace errors and warnings no Application Insights para procurar erros relacionados com a sua instância.

  2. Se a sua aplicação usar o modelo .NET em processo, considere ativar extended sessions. Sessões prolongadas minimizam as cargas de histórico, o que pode atrasar o processamento.

  3. Verifique se há gargalos de desempenho e escalabilidade. O uso elevado do CPU ou o grande consumo de memória podem causar atrasos. Para orientações detalhadas, consulte Desempenho e escala em Durable Functions.

Exemplos de consultas KQL para diagnósticos do Durable Functions

Resolva problemas escrevendo consultas personalizadas KQL na instância Aplicação Azure Insights configurada para a sua aplicação Funções do Azure. Para definições de colunas usadas nestas consultas, consulte a referência da coluna.

Mensagens de Armazenamento do Azure

Quando usa o fornecedor padrão do Armazenamento do Azure, todo o comportamento das Durable Functions é orientado por mensagens da fila do Armazenamento do Azure, e todo o estado relacionado com uma orquestração é armazenado em armazenamento de tabela e armazenamento de blobs. Quando ativa o rastreio do Durable Task Framework, todas as interações do Armazenamento do Azure são registadas no Application Insights. Estes dados são de importância crítica para a depuração de problemas de execução e desempenho.

A partir da versão 2.3.0 da extensão Durable Functions, pode publicar estes registos do Durable Task Framework na sua instância do Application Insights atualizando a sua configuração de registos no ficheiro host.json. Para mais informações, consulte o artigo de registo do Durable Task Framework.

A consulta seguinte inspeciona as interações do Armazenamento do Azure de ponta a ponta para uma instância de orquestração específica. Editar start e orchestrationInstanceID filtrar por intervalo de tempo e ID da instância.

let start = datetime(XXXX-XX-XXTXX:XX:XX); // edit this 
let orchestrationInstanceID = "XXXXXXX"; //edit this
traces  
| where timestamp > start and timestamp < start + 1h 
| where customDimensions.Category == "DurableTask.AzureStorage" 
| extend taskName = customDimensions["EventName"]
| extend eventType = customDimensions["prop__EventType"] 
| extend extendedSession = customDimensions["prop__IsExtendedSession"]
| extend account = customDimensions["prop__Account"] 
| extend details = customDimensions["prop__Details"] 
| extend instanceId = customDimensions["prop__InstanceId"] 
| extend messageId = customDimensions["prop__MessageId"] 
| extend executionId = customDimensions["prop__ExecutionId"] 
| extend age = customDimensions["prop__Age"] 
| extend latencyMs = customDimensions["prop__LatencyMs"] 
| extend dequeueCount = customDimensions["prop__DequeueCount"] 
| extend partitionId = customDimensions["prop__PartitionId"] 
| extend eventCount = customDimensions["prop__TotalEventCount"] 
| extend taskHub = customDimensions["prop__TaskHub"] 
| extend pid = customDimensions["ProcessId"]
| extend appName = cloud_RoleName
| extend newEvents = customDimensions["prop__NewEvents"]
| where instanceId == orchestrationInstanceID
| sort by timestamp asc
| project timestamp, appName, severityLevel, pid, taskName, eventType, message, details, messageId, partitionId, instanceId, executionId, age, latencyMs, dequeueCount, eventCount, newEvents, taskHub, account, extendedSession, sdkVersion

Erros de rastreamento e avisos

A consulta a seguir pesquisa erros e avisos para uma dada instância de orquestração. Forneça um valor para orchestrationInstanceID.

let orchestrationInstanceID = "XXXXXX"; // edit this
let start = datetime(XXXX-XX-XXTXX:XX:XX); 
traces  
| where timestamp > start and timestamp < start + 1h
| extend instanceId = iif(isnull(customDimensions["prop__InstanceId"] ) , customDimensions["prop__instanceId"], customDimensions["prop__InstanceId"] ) 
| extend logLevel = customDimensions["LogLevel"]
| extend functionName = customDimensions["prop__functionName"]
| extend status = customDimensions["prop__status"]
| extend details = customDimensions["prop__Details"] 
| extend reason = customDimensions["prop__reason"]
| where severityLevel >= 1 // to see all logs of severity level "Information" or greater.
| where instanceId == orchestrationInstanceID
| sort by timestamp asc 

Registos de fila de controlo e ID de partição

A consulta a seguir procura todas as atividades associadas à fila de controle de um instanceId. Forneça o valor do instanceID em orchestrationInstanceID e a hora de início da consulta em start.

let orchestrationInstanceID = "XXXXXX"; // edit this
let start = datetime(XXXX-XX-XXTXX:XX:XX); // edit this
traces  // determine control queue for this orchestrator
| where timestamp > start and timestamp < start + 1h 
| extend instanceId = customDimensions["prop__TargetInstanceId"] 
| extend partitionId = tostring(customDimensions["prop__PartitionId"])
| where partitionId contains "control" 
| where instanceId == orchestrationInstanceID
| join kind = rightsemi(
traces  
| where timestamp > start and timestamp < start + 1h 
| where customDimensions.Category == "DurableTask.AzureStorage" 
| extend taskName = customDimensions["EventName"]
| extend eventType = customDimensions["prop__EventType"] 
| extend extendedSession = customDimensions["prop__IsExtendedSession"]
| extend account = customDimensions["prop__Account"] 
| extend details = customDimensions["prop__Details"] 
| extend instanceId = customDimensions["prop__InstanceId"] 
| extend messageId = customDimensions["prop__MessageId"] 
| extend executionId = customDimensions["prop__ExecutionId"] 
| extend age = customDimensions["prop__Age"] 
| extend latencyMs = customDimensions["prop__LatencyMs"] 
| extend dequeueCount = customDimensions["prop__DequeueCount"] 
| extend partitionId = tostring(customDimensions["prop__PartitionId"])
| extend eventCount = customDimensions["prop__TotalEventCount"] 
| extend taskHub = customDimensions["prop__TaskHub"] 
| extend pid = customDimensions["ProcessId"]
| extend appName = cloud_RoleName
| extend newEvents = customDimensions["prop__NewEvents"]
) on partitionId
| sort by timestamp asc
| project timestamp, appName, severityLevel, pid, taskName, eventType, message, details, messageId, partitionId, instanceId, executionId, age, latencyMs, dequeueCount, eventCount, newEvents, taskHub, account, extendedSession, sdkVersion

Referência de colunas do Application Insights para consultas de Durable Functions

A tabela seguinte lista as colunas projetadas pelas consultas anteriores e as suas descrições.

Coluna Descrição
PID ID do processo da instância do aplicativo de função. Este valor é útil para verificar se o processo foi reciclado enquanto uma orquestração estava a decorrer.
Nome da tarefa O nome do evento que está sendo registrado.
eventType O tipo de mensagem, que geralmente representa o trabalho feito por um orquestrador. Para uma lista completa de valores possíveis e as suas descrições, veja EventType.cs.
sessão prolongada Valor booleano que indica se as sessões estendidas estão ativadas.
conta A conta de armazenamento usada pelo aplicativo.
details Informações adicionais sobre um evento específico, se disponíveis.
instanceId A ID de uma determinada orquestração ou instância de entidade.
ID da mensagem O ID único do Armazenamento do Azure para uma mensagem de fila específica. Esse valor geralmente aparece em eventos de rastreamento ReceivedMessage, ProcessingMessage e DeletingMessage. Este valor não está presente nos eventos do SendingMessage porque o ID da mensagem é gerado por Armazenamento do Azure após a mensagem é enviada.
ID de execução ID da execução do orquestrador, que muda sempre que continue-as-new é invocado.
idade O número de milissegundos desde que uma mensagem foi enfileirada. Grandes números geralmente indicam problemas de desempenho. Uma exceção é o tipo de mensagem TimerFired, que pode ter um valor de Idade elevado dependendo da duração do temporizador.
latencyMs O número de milissegundos tomados por alguma operação de armazenamento.
dequeueCount O número de vezes que uma mensagem é desalinhada. Em circunstâncias normais, este valor é sempre 1. Se forem mais do que uma, pode haver um problema.
ID de partição O nome da fila associada a esse log.
contagemTotalDeEventos O número de eventos históricos envolvidos na ação atual.
taskHub O nome do seu centro de tarefas.
novosEventos Uma lista, separada por vírgulas, dos eventos do histórico que estão a ser escritos na tabela Histórico na área de armazenamento.

Questões de gestão de ligações no plano de Consumo

As aplicações em execução no plano Funções do Azure de Consumo estão sujeitas a limites de ligação. Os sintomas comuns incluem:

  • Erros intermitentes de conectividade ao chamar funções de atividade ou serviços externos.
  • Orquestrações que falham esporadicamente sob carga.
  • Erros de exaustão de sockets nos logs.

Para reduzir o uso da ligação, utilize HttpClientFactory ou clientes estáticos compartilhados em vez de criar novas instâncias HttpClient em cada chamada de função. Para orientações detalhadas sobre pooling de ligações e melhores práticas, consulte Gerencie ligações em Funções do Azure.

Sugestões gerais

Sugestão

Antes de entrar em passos específicos de resolução de problemas, certifique-se de que a sua aplicação utiliza a versão mais recente da extensão Durable Functions. Na maioria das vezes, o uso da versão mais recente atenua problemas conhecidos já relatados por outros usuários. Para instruções sobre como atualizar, consulte versão da extensão do Upgrade Durable Functions.

O separador Diagnosticar e resolver problemas no portal Azure pode ajudar a monitorizar e diagnosticar problemas relacionados com a sua aplicação e sugerir soluções potenciais. Para mais informações, consulte Diagnósticos da app do Azure Functions.

Obtenha apoio para questões relacionadas às Durable Functions

Se não conseguir resolver o seu problema usando este guia, pode abrir um pedido de suporte ao abrir a blade Novo pedido de Suporte na secção Suporte + resolução de problemas da página da sua aplicação de funções no Portal do Azure.

Captura de ecrã da página de pedido de suporte no portal Azure.

Para questões e apoio da comunidade, abra uma edição num dos seguintes repositórios do GitHub. Quando reportar um bug, inclua informações como IDs de instância afetados, intervalos de tempo no UTC que mostrem o problema, o nome da aplicação (se possível) e a região de implementação para acelerar as investigações.