Durable Functions Guia de Resolução de Problemas
Durable Functions é uma extensão de Funções do Azure que lhe permite criar orquestrações sem servidor com código comum. Para obter mais informações sobre Durable Functions, consulte a descrição geral do Durable Functions.
Este artigo fornece um guia para a resolução de problemas de cenários comuns em aplicações Durable Functions.
Nota
Os engenheiros de suporte da Microsoft estão disponíveis para ajudar no diagnóstico de problemas com a sua aplicação. Se não conseguir diagnosticar o problema com este guia, pode apresentar um pedido de suporte ao aceder ao painel Novo pedido de Suporte na secção Suporte + resolução de problemas da página da aplicação de funções no portal do Azure.
Dica
Ao depurar e diagnosticar problemas, recomenda-se que comece por garantir que a sua aplicação está a utilizar a versão mais recente Durable Functions extensão. Na maioria das vezes, a utilização da versão mais recente mitiga problemas conhecidos já comunicados por outros utilizadores. Leia o artigo Atualizar Durable Functions versão da extensão para obter instruções sobre como atualizar a versão da extensão.
O separador Diagnosticar e resolver problemas no portal do Azure é um recurso útil para monitorizar e diagnosticar possíveis problemas relacionados com a sua aplicação. Também fornece potenciais soluções para os seus problemas com base no diagnóstico. Veja Diagnósticos da aplicação de Funções do Azure para obter mais detalhes.
Se os recursos acima não resolverem o problema, as secções seguintes fornecem conselhos para sintomas específicos da aplicação:
A orquestração está bloqueada no Pending
estado
Quando inicia uma orquestração, é escrita uma mensagem "iniciar" numa fila interna gerida pela extensão Durable e o estado da orquestração é definido como "Pendente". Depois de a mensagem de orquestração ser recolhida e processada com êxito por uma instância de aplicação disponível, o estado transitará para o estado "Em execução" (ou para outro estado não pendente).
Utilize os seguintes passos para resolver problemas de instâncias de orquestração que permanecem bloqueadas indefinidamente no estado "Pendente".
Verifique se existem avisos ou erros nos rastreios do Durable Task Framework para obter o ID da instância de orquestração afetado. Pode encontrar uma consulta de exemplo na secção Erros/Avisos de Rastreio.
Verifique as filas de controlo do Armazenamento do Azure atribuídas ao orquestrador bloqueado para ver se a "mensagem de início" ainda está lá Para obter mais informações sobre as filas de controlo, consulte a documentação da fila de controlo do fornecedor de Armazenamento do Azure.
Altere a versão de configuração da plataforma da sua aplicação para "64 Bits". Por vezes, as orquestrações não são iniciadas 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. Isto aplica-se apenas aos planos Básico, Standard, Premium e Elastic Premium Serviço de Aplicações. Os planos gratuitos ou de Consumo não suportam processos de 64 bits.
A orquestração começa após um longo atraso
Normalmente, as orquestrações começam dentro de alguns segundos depois de serem agendadas. No entanto, existem determinados casos em que as orquestrações podem demorar mais tempo a começar. Utilize os seguintes passos para resolver problemas quando as orquestrações demoram mais de alguns segundos a começar a ser executadas.
Veja a documentação sobre orquestrações atrasadas no Armazenamento do Azure para verificar se o atraso pode ser causado por limitações conhecidas.
Verifique se existem avisos ou erros nos rastreios do Durable Task Framework com o ID da instância de orquestração afetado. Pode encontrar uma consulta de exemplo na secção Erros/Avisos de Rastreio.
A orquestração não é concluída/está bloqueada no Running
estado
Se uma orquestração permanecer no estado "Em Execução" por um longo período de tempo, normalmente significa que está à espera de uma tarefa de execução prolongada que está agendada para ser concluída. Por exemplo, pode estar à espera que uma tarefa de temporizador durável, uma tarefa de atividade ou uma tarefa de evento externo sejam concluídas. No entanto, se observar que as tarefas agendadas foram concluídas com êxito, mas a orquestração ainda não está a progredir, poderá haver um problema ao impedir que a orquestração avance para a sua próxima tarefa. Muitas vezes, referimo-nos a orquestrações neste estado como "orquestrações bloqueadas".
Utilize os seguintes passos para resolver problemas de orquestrações bloqueadas:
Tente reiniciar a aplicação de funções. Este passo pode ajudar se a orquestração ficar bloqueada devido a um erro transitório ou a um impasse na aplicação ou no código da extensão.
Verifique as filas de controlo da conta de Armazenamento do Azure para ver se alguma fila está a crescer continuamente. Esta consulta KQL de mensagens do Armazenamento do Azure pode ajudar a identificar problemas com a desaplicação de mensagens de orquestração. Se o problema afetar apenas uma única fila de controlo, poderá indicar um problema que existe apenas numa instância de aplicação específica, caso em que aumentar ou reduzir verticalmente para sair da instância da VM em mau estado de funcionamento pode ajudar.
Utilize a consulta do Application Insights na secção Mensagens de Armazenamento do Azure para filtrar esse nome de fila como O ID da Partição e procurar quaisquer problemas relacionados com essa partição de fila de controlo.
Consulte a documentação de orientação no Durable Functions Melhores Práticas e Ferramentas de Diagnóstico. Alguns problemas podem ser causados por anti-padrões conhecidos Durable Functions.
Veja a documentação do Durable Functions Versioning. Alguns problemas podem ser causados por alterações interruptivas nas instâncias de orquestração a bordo.
A orquestração é executada lentamente
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. Utilize os seguintes passos para resolver problemas de orquestrações que estão a demorar mais tempo do que o esperado para serem executadas:
Verifique se existem avisos ou erros nos rastreios do Durable Task Framework para obter o ID da instância de orquestração afetado. Pode encontrar uma consulta de exemplo na secção Erros/Avisos de Rastreio.
Se a sua aplicação utilizar o modelo .NET no processo, considere ativar sessões prolongadas. As sessões prolongadas podem minimizar as cargas do histórico, o que pode abrandar o processamento.
Verifique se existem estrangulamentos de desempenho e escalabilidade. O desempenho da aplicação depende de muitos fatores. Por exemplo, uma utilização elevada da CPU ou um grande consumo de memória pode resultar em atrasos. Leia Desempenho e dimensionamento no Durable Functions para obter orientações detalhadas.
Consultas de Exemplo
Esta secção mostra como resolver problemas ao escrever consultas KQL personalizadas na instância do Aplicação Azure Insights configurada para a sua aplicação Funções do Azure.
Mensagens de Armazenamento do Azure
Ao utilizar o fornecedor de Armazenamento do Azure predefinido, todos os Durable Functions comportamento são impulsionados pelas mensagens de fila do Armazenamento do Azure e todo o estado relacionado com uma orquestração é armazenado no armazenamento de tabelas e no armazenamento de blobs. Quando o rastreio do Durable Task Framework está ativado, todas as interações do Armazenamento do Azure são registadas no Application Insights e estes dados são extremamente importantes para depurar problemas de execução e desempenho.
A partir da v2.3.0 da extensão Durable Functions, pode publicar estes registos do Durable Task Framework na sua instância do Application Insights ao atualizar a configuração de registo no ficheiro host.json. Veja o artigo Registo do Durable Task Framework para obter informações e instruções sobre como fazê-lo.
A seguinte consulta destina-se a inspecionar interações ponto a ponto do Armazenamento do Azure para uma instância de orquestração específica. Editar start
e orchestrationInstanceID
filtrar por intervalo de tempo e ID de 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 Rastreio
A consulta seguinte procura erros e avisos para uma determinada instância de orquestração. Terá de fornecer 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
Controlar a fila/Registos de ID de Partição
A consulta seguinte procura toda a atividade associada à fila de controlo de um instanceId. Terá de fornecer o valor do 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 da coluna do Application Insights
Segue-se uma lista das colunas projetadas pelas consultas acima e as respetivas descrições.
Coluna | Descrição |
---|---|
pid | ID do processo da instância da aplicação de funções. Isto é útil para determinar se o processo foi reciclado enquanto uma orquestração estava a ser executada. |
taskName | O nome do evento a ser registado. |
eventType | O tipo de mensagem, que normalmente representa o trabalho realizado por um orquestrador. Está aqui uma lista completa dos respetivos valores e descrições |
extendedSession | Valor booleano que indica se as sessões prolongadas estão ativadas. |
conta | A conta de armazenamento utilizada pela aplicação. |
detalhes | Informações adicionais sobre um evento específico, se disponível. |
instanceId | O ID de uma determinada instância de orquestração ou entidade. |
messageId | O ID de Armazenamento do Azure exclusivo para uma determinada mensagem de fila. Este valor aparece mais frequentemente em eventos de rastreio ReceivedMessage, ProcessingMessage e DeletingMessage. Tenha em atenção que não está presente nos eventos SendMessage porque o ID da mensagem é gerado pelo Armazenamento do Azure depois de enviarmos a mensagem. |
executionId | O ID da execução do orquestrador, que é alterado sempre que continue-as-new é invocado. |
idade | O número de milissegundos desde que uma mensagem foi colocada em fila. Os números grandes indicam frequentemente problemas de desempenho. Uma exceção é o tipo de mensagem TimerFired, que pode ter um grande valor Idade consoante a duração do temporizador. |
latênciaMs | O número de milissegundos tomados por alguma operação de armazenamento. |
dequeueCount | O número de vezes que uma mensagem foi desativada. Em circunstâncias normais, este valor é sempre 1. Se for mais do que um, poderá haver um problema. |
partitionId | O nome da fila associada a este registo. |
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 do histórico que estão a ser escritos na tabela Histórico no armazenamento. |