Guide de résolution des problèmes de Durable Functions
Durable Functions est une extension de la solution Azure Functions qui vous permet de créer des orchestrations serverless à l’aide de code ordinaire. Pour plus d’informations sur Durable Functions, consultez la Vue d’ensemble de Durable Functions.
Le guide fourni dans cet article permet de résoudre des problèmes de scénarios courants dans les applications Durable Functions.
Notes
Les ingénieurs du support technique Microsoft sont disponibles pour vous aider à diagnostiquer les problèmes liés à votre application. Si vous ne parvenez pas à diagnostiquer votre problème à l’aide de ce guide, vous pouvez créer un ticket de support en accédant au panneau Nouvelle demande de support, section Support + résolution des problèmes de la page de votre application de fonction dans le portail Azure.
Conseil
Lors du débogage et du diagnostic des problèmes, nous vous recommandons de commencer par vous assurer que votre application utilise la dernière version de l’extension Durable Functions. La plupart du temps, l’utilisation de la dernière version atténue les problèmes connus déjà signalés par d’autres utilisateurs. Consultez l’article Mettre à niveau la version de l’extension Durable Functions pour obtenir des instructions sur la procédure de mise à niveau de la version de votre extension.
L’onglet Diagnostiquer et résoudre les problèmes du portail Azure est une ressource utile pour surveiller et diagnostiquer les éventuels problèmes liés à votre application. Il fournit également des solutions possibles à vos problèmes en fonction du diagnostic. Pour plus d’informations, consultez Diagnostics d’application Azure Functions.
Si les ressources ci-dessus n’ont pas résolu votre problème, les sections suivantes fournissent des conseils par rapport à des symptômes spécifiques de l’application :
L’orchestration est bloquée dans l’état Pending
Lorsque vous démarrez une orchestration, un message de « démarrage » est écrit dans une file d’attente interne gérée par l’extension Durable, et l’état de l’orchestration est défini sur « En attente ». Une fois le message d’orchestration récupéré et traité avec succès par une instance d’application disponible, l’état passe à « En cours d’exécution » (ou à un autre état non « En attente »).
Effectuez les étapes suivantes pour résoudre les problèmes liés aux instances d’orchestration qui restent bloquées indéfiniment dans l’état « En attente ».
Vérifiez les traces de l’infrastructure des tâches durables à la recherche d’avertissements ou d’erreurs pour l’ID de l’instance d’orchestration impactée. Un exemple de requête est à votre disposition dans la section Tracer les erreurs/avertissements.
Vérifiez les files d’attente de contrôle du stockage Azure affectées à l’orchestrateur bloqué, pour voir si son « message de démarrage » est toujours là. Pour plus d’informations sur les files d’attente de contrôle, consultez la documentation sur la file d’attente de contrôle du fournisseur de stockage Azure.
Remplacez la version de la configuration de la plateforme de votre application par « 64 bits ». Parfois, les orchestrations ne démarrent pas, car l’application manque de mémoire. Le passage au processus 64 bits permet à l’application d’allouer plus de mémoire totale. Cette solution s’applique uniquement aux plans App Service De base, Standard, Premium et Premium élastique. Les plans Gratuit ou Consommation ne prennent pas en charge les processus 64 bits.
L’orchestration démarre après un long délai
Normalement, les orchestrations démarrent quelques secondes après leur planification. Toutefois, il existe certains cas où le démarrage des orchestrations peut prendre plus de temps. Effectuez les étapes suivantes pour résoudre les problèmes d’exécution des orchestrations qui prennent plus de quelques secondes pour démarrer.
Reportez-vous à la documentation sur les orchestrations retardées dans le stockage Azure pour vérifier si le retard peut être dû à des limitations connues.
Vérifiez les traces de l’infrastructure des tâches durables à la recherche d’avertissements ou d’erreurs pour l’ID de l’instance d’orchestration impactée. Un exemple de requête est à votre disposition à la section Tracer les erreurs/avertissements.
L’orchestration ne se termine pas ou est bloquée dans l’état Running
Si une orchestration reste à l’état « En cours d’exécution » pendant une longue période, cela signifie généralement qu’elle attend une tâche de longue durée qui est planifiée pour se terminer. Par exemple, il peut s’agir d’attendre l’exécution d’une tâche de minuteur durable, d’une tâche d’activité ou d’une tâche d’événement externe. Toutefois, si vous constatez que les tâches planifiées se sont terminées correctement, mais que l’orchestration ne progresse toujours pas, un problème peut exister qui empêche l’orchestration de passer à la tâche suivante. Nous faisons souvent référence aux orchestrations dans cet état sous l’appellation « orchestrations bloquées ».
Pour résoudre les problèmes d’orchestrations bloquées, effectuez les étapes suivantes :
Essayez de redémarrer l’application de fonction. Cette étape peut vous aider si l’orchestration est bloquée en raison d’un bogue ou d’un blocage temporaire dans l’application ou le code de l’extension.
Vérifiez les files d’attente de contrôle du compte de stockage Azure pour voir si des files d’attente grossissent de façon continue. Cette requête KQL de la messagerie Stockage Azure peut vous aider à identifier les problèmes liés au retrait des messages d’orchestration de la file d’attente. Si le problème n’affecte qu’une seule file d’attente de contrôle, il peut indiquer un problème existant uniquement sur une instance d’application spécifique, auquel cas effectuer un scale-up ou un scale-down pour retirer l’instance de machine virtuelle non saine pourrait vous aider.
Utilisez la requête Application Insights dans la section Messagerie Stockage Azure pour filtrer le nom de cette file d’attente en tant qu’ID de partition, et rechercher les problèmes liés à cette partition de file d’attente de contrôle.
Consultez les conseils des Bonnes pratiques et outils de diagnostic Durable Functions. Certains problèmes peuvent être dus à des anti-modèles Durable Functions connus.
Consultez la documentation sur le contrôle de version Durable Functions. Certains problèmes peuvent être causés par des changements cassants apportés aux instances d’orchestration se trouvant en version d’évaluation.
L’orchestration s’exécute lentement
Un traitement de grandes quantités de données, des erreurs internes et des ressources de calcul insuffisantes peuvent ralentir l’exécution des orchestrations. Procédez comme suit pour résoudre les problèmes d’exécution des orchestrations qui prennent plus de temps que prévu :
Vérifiez les traces de l’infrastructure des tâches durables à la recherche d’avertissements ou d’erreurs pour l’ID de l’instance d’orchestration impactée. Un exemple de requête est à votre disposition dans la section Tracer les erreurs/avertissements.
Si votre application utilise le modèle in-process .NET, songez à activer des sessions étendues. Les sessions étendues peuvent réduire les charges d’historique, ce qui peut ralentir le traitement.
Vérifiez les goulots d’étranglement des performances et de la scalabilité. Les performances des applications sont tributaires de nombreux facteurs. Par exemple, une utilisation intensive du processeur ou une consommation importante de mémoire peut entraîner des retards. Pour obtenir des conseils détaillés, consultez Performances et mise à l’échelle dans Durable Functions.
Exemples de requêtes
Cette section montre comment résoudre des problèmes en écrivant des requêtes KQL personnalisées dans l’instance Azure Application Insights configurée pour votre application Azure Functions.
Messagerie Stockage Azure
Lorsque vous utilisez le fournisseur de stockage Azure par défaut, tous les comportements Durable Functions sont pilotés par les messages de file d’attente du stockage Azure, et tout état lié à une orchestration est stocké dans le stockage de tables et le stockage d’objets blob. Lorsque le traçage de l’infrastructure des tâches durables est activé, toutes les interactions du stockage Azure sont consignées dans Application Insights, et ces données sont extrêmement importantes pour le débogage des problèmes d’exécution et de performances.
À compter de la version 2.3.0 de l’extension Durable Functions, vous pouvez publier ces journaux de l’infrastructure des tâches durables dans votre instance Application Insights en mettant à jour votre configuration de journalisation dans le fichier host.json. Pour plus d’informations et d’instructions sur la procédure à suivre, consultez l’article sur la journalisation de l’infrastructure des tâches durables.
La requête suivante permet d’inspecter les interactions du stockage Azure de bout en bout pour une instance d’orchestration particulière. Modifiez start
et orchestrationInstanceID
pour filtrer par intervalle de temps et ID d’instance.
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
Tracer les erreurs/avertissements
La requête suivante recherche des erreurs et des avertissements pour une instance d’orchestration donnée. Vous devez fournir une valeur pour 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
Journaux de file d’attente de contrôle/d’ID de partition
La requête suivante recherche toutes les activités associées à la file d’attente de contrôle d’un ID d’instance. Vous devez fournir la valeur d’instanceID dans orchestrationInstanceID
et l’heure de début de la requête dans 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
Informations de référence sur la colonne Application Insights
Vous trouverez ci-dessous une liste des colonnes projetées par les requêtes ci-dessus, et leurs descriptions respectives.
Colonne | Description |
---|---|
pid | ID de processus de l’instance d’application de fonction. Cela est utile pour déterminer si le processus a été recyclé pendant l’exécution d’une orchestration. |
taskName | Nom de l’événement journalisé. |
eventType | Type de message, qui représente généralement le travail effectué par un orchestrateur. La liste complète de ses valeurs possibles, ainsi que leurs descriptions, est ici |
extendedSession | Valeur booléenne indiquant si l’option des sessions étendues est activée. |
account | Compte de stockage utilisé par l’application. |
details | Informations supplémentaires sur un événement particulier, le cas échéant. |
instanceId | ID d’une orchestration ou d’une instance d’entité donnée. |
messageId | ID du stockage Azure unique pour un message de file d’attente donné. Cette valeur apparaît le plus souvent dans les événements de trace ReceivedMessage, ProcessingMessage et DeletingMessage. Notez qu’il n’est PAS présent dans les événements SendMessage, car l’ID de message est généré par le stockage Azure après l’envoi du message. |
executionId | ID d’exécution de l’orchestrateur, qui change à chaque appel de continue-as-new . |
age | Nombre de millisecondes depuis qu’un message a été mis en file d’attente. De grands nombres indiquent souvent des problèmes de performances. Une exception est le type de message TimerFired, qui peut avoir une valeur Age élevée en fonction de la durée du minuteur. |
latencyMs | Nombre de millisecondes prises par une opération de stockage. |
dequeueCount | Nombre de fois qu’un message a été enlevé de la file d’attente. En temps normal, cette valeur est toujours 1. Si elle est supérieure à un, il peut y avoir un problème. |
partitionId | Nom de la file d’attente associée à ce journal. |
totalEventCount | Nombre d’événements d’historique impliqués dans l’action actuelle. |
taskHub | Nom de votre hub de tâches. |
newEvents | Liste, séparée par des virgules, des événements d’historique en cours d’écriture dans la table de l’historique du stockage. |