Guia de Solução de Problemas do Durable Functions
O Durable Functions é uma extensão do Azure Functions que permite criar orquestrações sem servidor usando um código comum. Para obter mais informações sobre o Durable Functions, confira a Visão Geral do Durable Functions.
Este artigo fornece um guia para solucionar problemas de cenários comuns em aplicativos do Durable Functions.
Observação
Os engenheiros de suporte da Microsoft estão disponíveis para ajudar a diagnosticar problemas do seu aplicativo. Se não conseguir diagnosticar seu problema usando este guia, você poderá enviar um tíquete de suporte acessando a folha Nova Solicitação de Suporte na seção Suporte + solução de problemas da página do seu aplicativo de funções no portal do Azure.
Dica
Ao depurar e diagnosticar problemas, é recomendável que você comece garantindo que seu aplicativo esteja usando a versão mais recente da extensão do Durable Functions. Na maioria das vezes, o uso da versão mais recente atenua problemas conhecidos já notificados por outros usuários. Leia o artigo Atualizar a versão da extensão do Durable Functions para obter instruções sobre como atualizar a sua versão da extensão.
A guia Diagnosticar e resolver problemas no portal do Azure é um recurso útil para monitorar e diagnosticar possíveis problemas relacionados ao seu aplicativo. Além disso, fornece possíveis soluções para os seus problemas com base no diagnóstico. Confira Diagnósticos de aplicativos do Azure Functions para obter mais detalhes.
Se os recursos acima não resolverem seu problema, as seções a seguir fornecerão orientações relacionadas a sintomas específicos do aplicativo:
A orquestração está empacada no estado Pending
Quando você começa uma orquestração, uma mensagem "iniciar" é gravada em uma fila de espera interna gerenciada pela extensão do Durable, e o status da orquestração é definido como "Pendente". Após a mensagem de orquestração ter sido selecionada e processada com sucesso por uma instância do aplicativo disponível, o status fará a transição para "Em execução" (ou para algum outro estado que não seja "Pendente").
Use as etapas a seguir para solucionar problemas de instâncias de orquestração que permanecem empacadas indefinidamente no estado "Pendente".
Verifique os rastreamentos da Estrutura de Tarefas do Durable para detectar avisos ou erros da ID da instância de orquestração afetada. Uma consulta simples pode ser encontrada na seção Rastrear Erros/Avisos.
Verifique as filas de espera do controle do Armazenamento do Azure atribuídas ao orquestrador empacado para ver se a sua mensagem "iniciar" continua lá. Para obter mais informações sobre filas de espera do controle, confira a documentação da fila de espera do controle do provedor do Armazenamento do Microsoft Azure.
Altere a versão da configuração da plataforma do seu 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. Isso se aplica somente aos planos do Serviço de Aplicativo Básico, Standard, Premium e Elastic Premium. Os planos Gratuito ou Consumo não são compatíveis com processos de 64 bits.
A orquestração começa após um longo atraso
Normalmente, as orquestrações começam alguns segundos após terem sido agendadas. No entanto, há certos casos em que as orquestrações podem levar mais tempo para começar. Use as etapas a seguir para solucionar problemas quando as orquestrações levarem mais de alguns segundos para iniciar a execução.
Consulte a documentação sobre orquestrações atrasadas no Armazenamento do Microsoft Azure para verificar se o atraso pode estar sendo causado por limitações conhecidas.
Verifique os rastreamentos da Estrutura de Tarefas do Durable para detectar avisos ou erros relativos à ID da instância de orquestração afetada. Uma consulta simples pode ser encontrada na seção Rastrear Erros/Avisos.
A orquestração não consegue ser concluída/está empacada no estado Running
Se uma orquestração permanecer no estado "Em execução" por um longo tempo, isso geralmente significa que está aguardando a conclusão de uma tarefa agendada de longa duração. Por exemplo, pode estar aguardando a conclusão de uma tarefa do temporizador do Durable, uma tarefa de atividade ou uma tarefa de evento externo. No entanto, se você observar que as tarefas agendadas foram concluídas com sucesso, mas a orquestração continuar a não progredir, pode haver um problema impedindo que a orquestração prossiga para a próxima tarefa. Muitas vezes nos referimos a orquestrações nesse estado como "orquestrações empacadas".
Use as etapas a seguir para solucionar problemas de orquestrações empacadas:
Tente reiniciar o aplicativo de funções. Essa etapa pode ajudar se a orquestração ficar empacada devido a um bug transitório ou a um deadlock no aplicativo ou no código da extensão.
Verifique as filas de espera do controle da conta do Armazenamento do Azure para ver se as filas estão crescendo continuamente. Essa consulta KQL de mensagens do Armazenamento do Azure pode ajudar a identificar problemas com a remoção de mensagens de orquestração da fila de espera. Se o problema estiver afetando apenas uma única fila de espera do controle, isso poderá indicar um problema que existe em apenas uma instância de aplicativo específica. Nesse caso, escalonar ou reduzir verticalmente para sair da instância de VM não íntegra pode ajudar.
Use a consulta do Application Insights na seção Mensagens do Armazenamento do Microsoft Azure para filtrar esse nome de fila de espera como a ID de Partição e procurar quaisquer problemas relacionados à referida partição da fila de espera do controle.
Confira as diretrizes no artigo Boas Práticas e Ferramentas de Diagnóstico do Durable Functions. Alguns problemas podem ser causados por antipadrões conhecidos do Durable Functions.
Verifique a documentação do Controle de Versão do Durable Functions. Alguns problemas podem ser causados por alterações interruptivas em instâncias de orquestração em execução.
A orquestração está sendo executada lentamente
Um processamento de dados intensivo, erros internos e recursos de computação insuficientes podem fazer com que as orquestrações sejam executadas mais lentamente do que o normal. Use as etapas a seguir para solucionar problemas de orquestrações que estão demorando mais do que o esperado para serem executadas:
Verifique os rastreamentos da Estrutura de Tarefas do Durable para detectar avisos ou erros da ID da instância de orquestração afetada. Uma consulta simples pode ser encontrada na seção Rastrear Erros/Avisos.
Se o aplicativo utilizar o modelo em processo do .NET, pense em habilitar sessões prolongadas. As sessões prolongadas podem minimizar os carregamentos do histórico, que podem tornar o processamento mais lento.
Verifique se há gargalos de desempenho e escalabilidade. O desempenho do aplicativo depende de diversos fatores. Por exemplo, um alto uso da CPU ou um grande consumo de memória podem resultar em atrasos. Leia Desempenho e escala no Durable Functions para obter orientações detalhadas.
Consultas de exemplo
Esta seção mostra como solucionar problemas escrevendo consultas KQL personalizadas na instância do Azure Application Insights configurada para o seu aplicativo do Azure Functions.
Envio de mensagens do Armazenamento do Microsoft Azure
Quando você usa o provedor padrão do Armazenamento do Azure, todos os comportamentos do Durable Functions são controlados por mensagens da fila de espera do Armazenamento do Azure e todos os estados relacionados a uma orquestração são armazenados no armazenamento de tabelas e no armazenamento de blobs. Quando o rastreamento do Estrutura de Tarefas do Durable está habilitado, todas as interações do Armazenamento do Azure são registradas no log do Application Insights, e esses dados são extremamente importantes para depurar problemas de execução e desempenho.
A partir da v2.3.0 da extensão do Durable Functions, você pode fazer com que esses logs da Estrutura de Tarefas do Durable sejam publicados na instância do Application Insights atualizando a configuração do seu registro em log no arquivo host.json. Confira o artigo Registro em log da Estrutura de Tarefas do Durable para obter informações e instruções sobre como fazer isso.
A consulta a seguir destina-se a inspecionar interações de ponta a ponta do 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
Erros/Avisos de Rastreamento
A consulta a seguir pesquisa erros e avisos para uma determinada instância de orquestração. Você precisará fornecer um valor para a 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
Logs da fila de espera do controle/ID da partição
A consulta a seguir pesquisa todas as atividades associadas à fila de espera do controle de uma instanceId. Você precisará fornecer o valor para a instanceID no 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
Abaixo temos uma lista das colunas projetadas pelas consultas acima e suas respectivas descrições.
Coluna | Descrição |
---|---|
pid | ID do processo da instância do aplicativo de função. Isso é útil para determinar se o processo foi reciclado enquanto uma orquestração estava em execução. |
taskName | O nome do evento que está sendo registrado em log. |
eventType | O tipo de mensagem, que geralmente representa o trabalho feito por um orquestrador. Uma lista completa dos valores possíveis e suas descrições está disponível aqui |
extendedSession | Valor booliano indicando se as sessões prolongadas estão habilitadas. |
account | A conta de armazenamento usada pelo aplicativo. |
detalhes | Informações adicionais sobre um evento específico, se disponível. |
instanceId | A ID de uma determinada instância de orquestração ou entidade. |
messageId | A ID exclusiva do Armazenamento do Azure para uma determinada mensagem da fila de espera. Esse valor aparece com mais frequência nos eventos de rastreamento ReceivedMessage, ProcessingMessage e DeletingMessage. Observe que NÃO está presente nos eventos SendMessage porque a ID da mensagem é gerada pelo Armazenamento do Azure após a mensagem ter sido enviada. |
executionId | A ID da execução do orquestrador, que é alterada sempre que continue-as-new é invocado. |
age | O número de milissegundos decorridos desde que uma mensagem foi adicionada à fila de espera. 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 gasto por alguma operação de armazenamento. |
dequeueCount | O número de vezes que uma mensagem foi removida da fila de espera. Em circunstâncias normais, esse valor é sempre 1. Se for mais de um, pode haver algum problema. |
partitionId | O nome da fila de espera associada a esse log. |
totalEventCount | O número de eventos do histórico envolvidos na ação atual. |
taskHub | O nome do seu hub de tarefas. |
newEvents | Uma lista separada por vírgulas de eventos de histórico que estão sendo gravados na tabela Histórico do armazenamento. |