Durable Functions guia de solução de problemas

Este artigo ajuda você a solucionar problemas de cenários comuns em aplicativos Durable Functions. Encontre seu sintoma na lista a seguir e siga as etapas vinculadas para diagnosticar e resolver o problema.

Sintomas comuns

Para consultas de diagnóstico KQL que você pode executar no Application Insights, consulte Exemplos de consultas KQL para diagnósticos de Durable Functions.

A orquestração está travada no estado Pending

Ao iniciar uma orquestração, uma mensagem de "início" é gravada em uma fila interna gerenciada pela extensão Durable, e o status da orquestração é definido como "Pendente". Após uma instância de aplicativo disponível receber e processar com sucesso a mensagem de orquestração, o status passa para "Em execução" (ou para algum outro estado que não seja "Pendente").

Siga estes passos para solucionar problemas com instâncias de orquestração que permanecem travadas indefinidamente no estado "Pendente".

  1. Verifique os registros da Estrutura de Tarefas Duráveis em busca de avisos ou erros para a ID da instância de orquestração afetada. Use a consulta de erros de rastreamento e avisos no Application Insights para pesquisar erros relacionados à sua instância.

  2. Verifique as filas de controle 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 Queues e procure filas com um prefixo control. Para obter informações sobre como as filas de controle funcionam, consulte a documentação da fila de controle do provedor Armazenamento do Azure.

  3. Altere a configuração da plataforma do aplicativo para 64 Bits. Às vezes, as orquestrações não são iniciadas porque o aplicativo está ficando sem memória. Alternar para um processo de 64 bits permite que o aplicativo aloque mais memória total. Essa alteração só se aplica aos planos Basic, Standard, Premium e Elastic Premium do Serviço de Aplicativo. Planos gratuitos ou de consumo não dão suporte a processos de 64 bits.

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

Normalmente, as orquestrações começam em alguns segundos depois de serem agendadas. No entanto, as orquestrações podem demorar mais para começar em determinados casos. Siga estas etapas para solucionar problemas quando as orquestrações levarem mais de alguns segundos para iniciar a execução.

  1. Verifique se o atraso corresponde a uma limitação conhecida do provedor de Armazenamento do Azure, como reequilibramento de partição ou intervalos de sondagem baseados em temporizador.

  2. Verifique os rastreamentos do Framework de Tarefas Duráveis para identificar avisos ou erros associados à ID da instância de orquestração afetada. Use a consulta de erros de rastreamento e avisos no Application Insights para pesquisar erros relacionados à sua instância.

A orquestração está travada no estado Running

Se o status da sua orquestração mostrar "Em Execução" por mais tempo do que o esperado, ou se parecer que parou de progredir, é provável que a orquestração esteja aguardando uma tarefa que não foi concluída. Por exemplo, pode estar aguardando um temporizador durável, uma tarefa de atividade ou um evento externo. Se as tarefas agendadas forem concluídas com êxito, mas a orquestração ainda não estiver avançando, poderá haver um problema impedindo que ela prossiga para a próxima etapa. Orquestrações nesse estado geralmente são chamadas de "orquestrações paralisadas".

Siga estas etapas para solucionar problemas de orquestrações paralisadas:

  1. Tente reiniciar o aplicativo de funções. Essa etapa pode ajudar se a orquestração ficar paralisada devido a um bug ou deadlock transitório no aplicativo ou no código de extensão.

  2. Verifique as filas de controle de conta Armazenamento do Azure para ver se as filas estão crescendo continuamente. Use a consulta de mensagens do Armazenamento do Azure no Application Insights para identificar problemas com a remoção de mensagens da fila de orquestração. Se o problema afetar apenas uma única fila de controle, ele poderá indicar um problema em uma instância de aplicativo específica. Nesse caso, aumentar ou diminuir a escala para migrar da instância de VM com problemas pode ajudar.

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

  4. Verifique a documentação Durable Functions Versioning. Alterações significativas em instâncias de orquestração em andamento podem causar orquestrações travadas.

A orquestração leva mais tempo do que o esperado para ser concluída

O processamento de dados pesados, erros internos e recursos de computação insuficientes podem fazer com que as orquestrações sejam executadas mais lentamente do que o normal. Siga estas etapas para solucionar problemas de orquestrações que levam mais tempo do que o esperado para serem concluídas:

  1. Verifique os rastreamentos da Estrutura de Tarefas do Durable para detectar avisos ou erros da ID da instância de orquestração afetada. Use a consulta de erros de rastreamento e avisos no Application Insights para pesquisar erros relacionados à sua instância.

  2. Se o aplicativo usar o modelo .NET in-process, considere habilitar sessões estendidas. As sessões estendidas minimizam as cargas de histórico, o que pode desacelerar o processamento.

  3. Verifique se há gargalos de desempenho e escalabilidade. O alto uso da CPU ou o consumo de memória grande podem causar atrasos. Para obter orientações detalhadas, consulte Desempenho e dimensionamento em Funções Duráveis.

Exemplos de consultas KQL para diagnósticos de Durable Functions

Solucione problemas escrevendo consultas KQL personalizadas na instância do Aplicativo Azure Insights configurada para seu aplicativo Azure Functions. Para definições de coluna usadas nessas consultas, consulte a referência de coluna.

Mensagens do Armazenamento do Azure

Ao usar o provedor de Armazenamento do Azure padrão, todo o comportamento das Funções Duráveis ​​é controlado por mensagens da fila do Armazenamento do Azure, e todo o estado relacionado a uma orquestração é armazenado no armazenamento de tabelas e no armazenamento de blobs. Quando você habilita o rastreamento do Durable Task Framework, todas as interações Armazenamento do Azure são registradas no Application Insights. Esses dados são extremamente importantes para depurar problemas de desempenho e execução.

A partir da v2.3.0 da extensão Durable Functions, você pode publicar esses logs da Estrutura de Tarefas Duráveis em sua instância do Application Insights atualizando sua configuração de log no arquivo host.json. Para obter mais informações, consulte o artigo de log do Durable Task Framework.

A consulta a seguir inspeciona as interações de ponta a ponta com o Armazenamento do Azure para uma instância de orquestração específica. Edite start e orchestrationInstanceID para 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

Rastrear erros e avisos

A consulta a seguir pesquisa erros e avisos para uma instância de orquestração específica. 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 

Fila de controle e logs de ID de partição

A consulta a seguir pesquisa todas as atividades associadas à fila de controle de uma instanceId. Forneça o valor para a instanceID dentro 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 coluna do Application Insights para consultas de Durable Functions

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

Coluna Descrição
pid ID do processo da instância do aplicativo de função. Esse valor é útil para verificar se o processo foi reiniciado enquanto uma orquestração estava em execução.
taskName O nome do evento que está sendo registrado.
eventType O tipo de mensagem, que geralmente representa o trabalho feito por um orquestrador. Para obter uma lista completa de possíveis valores e suas descrições, consulte EventType.cs.
extendedSession Valor booliano que indica se as sessões estendidas estão habilitadas.
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 instância de orquestração ou entidade.
ID da Mensagem O ID único do Armazenamento do Azure para uma determinada mensagem de fila. Esse valor aparece mais comumente em eventos de rastreamento ReceivedMessage, ProcessingMessage e DeletingMessage. Esse valor não está presente em eventos SendingMessage porque a ID da mensagem é gerada por Armazenamento do Azure after a mensagem é enviada.
ID de execução A ID da execução do orquestrador, que é alterada sempre que continue-as-new é invocado.
idade O número de milissegundos desde que uma mensagem foi enfileirada. Números grandes geralmente indicam problemas de desempenho. Uma exceção é o tipo de mensagem TimerFired, que pode ter um valor Age grande dependendo da duração do temporizador.
latencyMs O número de milissegundos obtidos por alguma operação de armazenamento.
dequeueCount O número de vezes que uma mensagem é removida da fila. Em circunstâncias normais, esse valor é sempre 1. Se for mais de um, pode haver um problema.
ID de partição O nome da fila associada a esse log.
totalEventCount O número de eventos de histórico envolvidos na ação atual.
taskHub O nome do Task Hub.
novosEventos Uma lista separada por vírgulas de eventos de histórico que estão sendo gravados na tabela Histórico do armazenamento.

Problemas de gerenciamento de conexão no plano de consumo

Os aplicativos em execução no plano de consumo Azure Functions estão sujeitos a limites de conexão. Os sintomas comuns incluem:

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

Para reduzir o uso da conexão, use HttpClientFactory ou compartilhe clientes estáticos em vez de criar novas HttpClient instâncias em cada chamada de função. Para obter diretrizes detalhadas sobre o pool de conexões e as práticas recomendadas, consulte Conectar conexões no Azure Functions.

Dicas gerais

Dica

Antes de se aprofundar em etapas específicas de solução de problemas, verifique se seu aplicativo usa a versão mais recente da extensão Durable Functions. Na maioria das vezes, usar a versão mais recente atenua problemas conhecidos já relatados por outros usuários. Para obter instruções sobre como atualizar, consulte atualizar a versão da extensão do Durable Functions.

A guia Diagnose e resolver problemas no portal Azure pode ajudar a monitorar e diagnosticar problemas relacionados ao aplicativo e sugerir possíveis soluções. Para obter mais informações, consulte Diagnósticos do aplicativo de funções do Azure.

Obtenha suporte para problemas com o Durable Functions

Se você não conseguir resolver o problema usando este guia, poderá registrar um tíquete de suporte abrindo o painel Novo pedido de suporte na seção suporte + solução de problemas da página do aplicativo de funções no portal do Azure.

Screenshot da página de solicitação de suporte no portal Azure.

Para perguntas e suporte à comunidade, abra um problema em um dos repositórios de GitHub a seguir. Ao relatar um bug, inclua informações como IDs de instância afetadas, intervalos de tempo em UTC mostrando o problema, o nome do aplicativo (se possível) e a região de implantação para acelerar as investigações.