guía de solución de problemas de Durable Functions

Este artículo le ayuda a solucionar problemas de escenarios comunes en aplicaciones Durable Functions. Busque su síntoma en la lista siguiente y siga los pasos vinculados para diagnosticar y resolver el problema.

Síntomas comunes

Para obtener ejemplos de consultas KQL para diagnóstico de Durable Functions que puede ejecutar en Application Insights, consulte Ejemplos de consultas KQL para diagnósticos de Durable Functions.

La orquestación está bloqueada en el estado Pending

Al iniciar una orquestación, se escribe un mensaje de "inicio" en una cola interna administrada por la extensión Durable y el estado de la orquestación se establece en "Pendiente". Después de que una instancia de aplicación disponible seleccione y procese correctamente el mensaje de orquestación, el estado pasa a "En ejecución" (o a algún otro estado que no sea "Pendiente").

Siga estos pasos para solucionar los problemas de las instancias de orquestación que permanecen atascadas indefinidamente en estado "Pendiente".

  1. Compruebe los seguimientos de Durable Task Framework para ver si hay advertencias o errores para el identificador de instancia de orquestación afectado. Use la consulta Seguimiento de errores y advertencias en Application Insights para buscar errores relacionados con la instancia.

  2. Compruebe las colas de control de Azure Storage para ver si el "mensaje de inicio" de la orquestación todavía está en la cola. En el portal de Azure, vaya a la cuenta de almacenamiento, seleccione Queues y busque colas con un prefijo control. Para obtener información sobre cómo funcionan las colas de control, consulte la documentación de la cola de control del proveedor de Azure Storage.

  3. Cambie la configuración de la plataforma de la aplicación a 64 bits. A veces, las orquestaciones no se inician porque la aplicación se está quedando sin memoria. Cambiar a un proceso de 64 bits permite que la aplicación asigne más memoria total. Este cambio solo se aplica a los planes Básico, Estándar, Premium y Elastic Premium de App Service. Los planes gratuitos o de consumo no admiten procesos de 64 bits.

Las orquestaciones comienzan después de un retraso largo

Normalmente, las orquestaciones comienzan en unos segundos después de ser programadas. Sin embargo, las orquestaciones pueden tardar más tiempo en iniciarse en determinados casos. Siga estos pasos para solucionar problemas cuando las orquestaciones tardan más de unos segundos en empezar a ejecutarse.

  1. Compruebe si el retraso coincide con una limitación conocida del proveedor de Azure Storage, como el reequilibrio de particiones o los intervalos de sondeo basados en temporizadores.

  2. Compruebe los rastros del Durable Task Framework para advertencias o errores con el ID de la instancia de orquestación afectada. Use la consulta Seguimiento de errores y advertencias en Application Insights para buscar errores relacionados con la instancia.

La orquestación está bloqueada en el estado Running

Si el estado de la orquestación muestra "En ejecución" durante más tiempo de lo esperado o si parece haber dejado de avanzar, es probable que la orquestación esté esperando una tarea que no se haya completado. Por ejemplo, podría estar esperando un temporizador duradero, una tarea de actividad o un evento externo. Si las tareas programadas se completan correctamente, pero la orquestación todavía no avanza, puede haber un problema que impida que continúe con su paso siguiente. Las orquestaciones en este estado a menudo se denominan "orquestaciones bloqueadas".

Siga estos pasos para solucionar problemas de orquestaciones bloqueadas:

  1. Intente reiniciar la aplicación de funciones. Este paso puede ayudar si la orquestación se bloquea debido a un error transitorio o interbloqueo en la aplicación o en el código de extensión.

  2. Compruebe las colas de control de la cuenta de Azure Storage para ver si alguna cola está creciendo continuamente. Utilice la consulta de mensajería Azure Storage en Application Insights para identificar problemas con la extracción de mensajes de orquestación. Si el problema afecta solo a una sola cola de control, podría indicar un problema en una instancia de aplicación específica. En ese caso, escalar hacia arriba o hacia abajo para alejarse de la instancia de máquina virtual no saludable podría ayudar.

  3. Filtre los resultados de la consulta de mensajería de Azure Storage por el nombre de la cola, usándolo como identificador de partición, para buscar problemas relacionados con esa partición específica de la cola de control.

  4. Consulte la documentación Durable Functions Control de versiones. Los cambios rupturistas en las instancias de orquestación en curso pueden provocar orquestaciones atascadas.

La orquestación tarda más de lo esperado en completarse

El procesamiento intensivo de datos, los errores internos y los recursos de proceso insuficientes pueden hacer que las orquestaciones se ejecuten más lentamente de lo normal. Siga estos pasos para solucionar problemas de orquestaciones que tardan más de lo esperado en completarse:

  1. Compruebe los seguimientos de Durable Task Framework para ver si hay advertencias o errores para el identificador de instancia de orquestación afectado. Use la consulta Seguimiento de errores y advertencias en Application Insights para buscar errores relacionados con la instancia.

  2. Si su aplicación usa el modelo .NET en-proceso, considere habilitar sesiones extendidas. Las sesiones extendidas minimizan las cargas del historial, lo que puede ralentizar el procesamiento.

  3. Compruebe si hay cuellos de botella de rendimiento y escalabilidad. El uso elevado de cpu o el consumo de memoria grande pueden provocar retrasos. Para obtener instrucciones detalladas, consulte Rendimiento y escalado en "Durable Functions".

Consultas KQL de ejemplo para los diagnósticos de Funciones Duraderas

Para solucionar problemas, escriba consultas personalizadas de KQL en la instancia de Aplicación de Azure Insights configurada para la aplicación de Azure Functions. Para ver las definiciones de columna que se usan en estas consultas, consulte la referencia de columna.

mensajería de almacenamiento de Azure

Cuando se utiliza el proveedor predeterminado de Azure Storage, el comportamiento de Durable Functions se controla mediante los mensajes de cola de Azure Storage, y todo el estado relacionado con una orquestación se almacena en el almacenamiento de tablas y el almacenamiento de blobs. Al habilitar el seguimiento de Durable Task Framework, todas las interacciones de Azure Storage se registran en Application Insights. Estos datos son fundamentalmente importantes para depurar problemas de ejecución y rendimiento.

A partir de la versión 2.3.0 de la extensión de Durable Functions, puede publicar estos registros de Durable Task Framework en la instancia de Application Insights actualizando la configuración de registro en el archivo host.json. Para obtener más información, consulte el Artículo de registro de Durable Task Framework.

La consulta siguiente inspecciona las interacciones de Azure Storage de un extremo a otro para una instancia de orquestación específica. Edite start y orchestrationInstanceID filtre por intervalo de tiempo e identificador de instancia.

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

Seguimiento de errores y advertencias

La consulta siguiente busca errores y advertencias para una instancia de orquestación determinada. Proporcione un 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 

Cola de control y registros de Id. de partición

La consulta siguiente busca toda la actividad asociada a la cola de control de instanceId. Proporcione el valor de instanceID en orchestrationInstanceID y la hora de inicio de la consulta en 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

Referencia de columnas para consultas de Durable Functions en Application Insights

En la tabla siguiente se enumeran las columnas proyectadas por las consultas anteriores y sus descripciones.

Columna Descripción
pid Id. de proceso de la instancia de la aplicación de funciones. Este valor resulta útil para comprobar si el proceso se recicló mientras se estaba ejecutando una orquestación.
taskName Nombre del evento que se registra.
eventType Tipo de mensaje, que normalmente representa el trabajo realizado por un orquestador. Para obtener una lista completa de los valores posibles y sus descripciones, consulte EventType.cs.
sesión extendida Valor booleano que indica si las sesiones extendidas están habilitadas.
cuenta La cuenta de almacenamiento usada por la aplicación.
details Información adicional sobre un evento determinado, si está disponible.
instanceId El Id. de una instancia de orquestación o entidad determinada.
ID de mensaje El identificador único de Azure Storage para un mensaje de cola determinado. Este valor aparece normalmente en los eventos de seguimiento ReceivedMessage, ProcessingMessage y DeletingMessage. Este valor no está presente en los eventos SendingMessage porque el ID del mensaje se genera en Azure Storage después de que el mensaje es enviado.
identificadorDeEjecución El Id. de la ejecución del orquestador, que cambia cada vez que se invoca continue-as-new.
edad Número de milisegundos desde que se puso en cola un mensaje. Los números grandes suelen indicar problemas de rendimiento. Una excepción es el tipo de mensaje TimerFired, que puede tener un valor Age grande en función de la duración del temporizador.
latencyMs Número de milisegundos tomados por alguna operación de almacenamiento.
dequeueCount El número de veces que un mensaje se ha quitado de la cola. En circunstancias normales, este valor siempre es 1. Si es más de uno, podría haber un problema.
partitionId Nombre de la cola asociada a este registro.
conteoTotalDeEventos Número de eventos de historial implicados en la acción actual.
taskHub Nombre de su centro de tareas.
nuevosEventos Una lista separada por comas de los eventos de historial que se están escribiendo en la tabla Historial almacenada.

Problemas de administración de conexiones en el Plan de Consumo

Las aplicaciones que se ejecutan en el plan de consumo de Azure Functions están sujetas a límites de conexión. Entre los síntomas comunes se incluyen:

  • Errores de conectividad intermitentes al llamar a funciones de actividad o servicios externos.
  • Orquestaciones que fallan esporádicamente bajo carga.
  • Errores de agotamiento de sockets en los registros.

Para reducir el uso de la conexión, use HttpClientFactory o comparta clientes estáticos en lugar de crear nuevas HttpClient instancias en cada llamada de función. Para obtener instrucciones detalladas sobre la agrupación de conexiones y los procedimientos recomendados, consulte Administrar conexiones en Azure Functions.

Sugerencias generales

Sugerencia

Antes de profundizar en pasos específicos de solución de problemas, asegúrese de que la aplicación usa la versión más reciente de la extensión Durable Functions. La mayoría de las veces, el uso de la versión más reciente mitiga los problemas conocidos que ya han notificado otros usuarios. Para obtener instrucciones sobre cómo actualizar, consulte Actualización de la extensión Durable Functions.

La pestaña Diagnose y resolver problemas del portal de Azure puede ayudar a supervisar y diagnosticar problemas relacionados con la aplicación y sugerir posibles soluciones. Para obtener más información, consulte Diagnósticos de aplicaciones de Azure Functions.

Obtención de soporte técnico para problemas de Durable Functions

Si no puede resolver el problema mediante esta guía, puede presentar una incidencia abriendo el panel Nueva solicitud de soporte técnico en el panel Support + troubleshooting de la página de la aplicación de funciones en el portal de Azure.

Captura de pantalla de la página de solicitud de soporte técnico en el Azure portal.

Para preguntas y soporte técnico de la comunidad, abra un problema en uno de los siguientes repositorios de GitHub. Al notificar un error, incluya información como identificadores de instancia afectados, intervalos de tiempo en UTC que muestran el problema, el nombre de la aplicación (si es posible) y la región de implementación para acelerar las investigaciones.