Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Este artículo le ayuda a diagnosticar y corregir problemas comunes al compilar aplicaciones con los SDK portátiles de Durable Task. Estos SDK se conectan al back-end del programador de tareas Durable y se ejecutan en cualquier plataforma de hospedaje, incluidos Azure Container Apps, Kubernetes y vm. Para ver problemas específicos del servicio Programador de tareas durables, consulte Solución de problemas del programador de tareas durables. Para problemas de Durable Functions, consulte la guía de solución de problemas de Durable Functions.
Sugerencia
El panel de monitoreo del programador de tareas duraderas es útil para inspeccionar el estado de la orquestación, ver el historial de ejecución e identificar fallos. Úselo junto con esta guía para acelerar la solución de problemas.
Encuentra tu problema
| Mensaje de error o síntoma | Section |
|---|---|
connection refused o failed to connect en el inicio |
El emulador no se está ejecutando o no es accesible |
| Errores en el análisis de la cadena de conexión o errores de autenticación al inicio | El formato de cadena de conexión es incorrecto |
| El worker se conecta, pero las orquestaciones no se inician | El centro de tareas no existe |
errores de 401 Unauthorized o identity/role en Azure |
Errores de autenticación basados en identidades en Azure |
| Orquestación bloqueada en "Pendiente" | La orquestación está bloqueada en el estado "Pendiente" |
| Orquestación bloqueada en "En ejecución" | La orquestación está bloqueada en el estado "En ejecución" |
| Errores de reproducción, bucles infinitos o comportamiento inesperado | Código de orquestador no determinista |
| Errores de incompatibilidad de tipos o de serialización JSON | Errores de serialización y deserialización |
activity not found |
Actividad no encontrada |
RESOURCE_EXHAUSTED o message too large |
Se superó el límite de tamaño del mensaje gRPC |
CANCELLED: Cancelled on client durante el apagado |
Errores de cancelación de flujos durante el apagado |
CS0419
/
VSTHRD105 advertencias interrumpen la construcción |
Advertencias del generador de origen interrumpen las compilaciones (C#) |
OrchestratorBlockedException (Java) |
OrchestratorBlockedException (Java) |
Error no útil al usar retry_policy (Python) |
La política de reintento requiere max_retry_interval (Python) |
Problemas de conexión y configuración
El emulador no se está ejecutando o no es accesible
Si se produce un error en el inicio de la aplicación con un error de conexión como "conexión rechazada" o "no se pudo conectar", compruebe que el emulador del Programador de tareas durable está en ejecución y accesible.
Compruebe que el contenedor de Docker del emulador se está ejecutando:
docker ps | grep durabletaskVerifique los mapeos correctos de puertos. El emulador expone dos puertos:
- 8080: punto de conexión gRPC (usado por la aplicación)
- 8082: interfaz de usuario del panel
Si usa una asignación de puertos personalizada, actualice el cadena de conexión para que coincida con el puerto host asignado al puerto de contenedor
8080.Pruebe la conectividad con el punto de conexión gRPC:
curl -v http://localhost:8080Una negativa de conexión indica que el contenedor no se está ejecutando o que la asignación de puertos es incorrecta.
El formato de cadena de conexión es incorrecto
Los errores de cadena de conexión son una causa común de errores de inicio. Compruebe que el cadena de conexión coincide con el formato esperado.
Desarrollo local (emulador):
Endpoint=http://localhost:8080;Authentication=None
Azure (identidad administrada):
Endpoint=https://<scheduler-name>.durabletask.io;Authentication=ManagedIdentity
Azure (identidad administrada asignada por el usuario):
Endpoint=https://<scheduler-name>.durabletask.io;Authentication=ManagedIdentity;ClientID=<client-id>
Errores comunes:
- Uso
httpspara el emulador local (el emulador usahttp) - Usar
httppara puntos de conexión de Azure (Azure requierehttps) - Omitir el
Authenticationparámetro - Uso del puerto del panel (
8082) en lugar del puerto gRPC (8080)
El cliente o el trabajador no se pueden conectar
Si el cliente o el trabajador no pueden conectarse, compruebe lo siguiente:
- La cadena de conexión coincide con el formato esperado que se muestra en Formato de cadena de conexión es incorrecto.
- El nombre del hub de tareas es el mismo para el cliente y el trabajador.
-
Endpoint URL usa
httppara el emulador local yhttpspara Azure.
Para obtener ejemplos completos de configuración en cada idioma, consulte Creación de una aplicación con SDK de Durable Task.
El centro de tareas no existe
Si las orquestaciones no se inician o el trabajador se conecta pero no procesa el trabajo, es posible que el centro de tareas no exista en el planificador. Normalmente, el emulador crea centros de tareas automáticamente mediante la variable de DTS_TASK_HUB_NAMES entorno.
Compruebe que el emulador se inició con el nombre correcto del centro de tareas:
docker run -d -p 8080:8080 -p 8082:8082 \
-e DTS_TASK_HUB_NAMES="my-taskhub" \
mcr.microsoft.com/dts/dts-emulator:latest
Para los programadores o planificadores hospedados en Azure, cree el centro de tareas mediante la CLI de Azure.
az durabletask taskhub create \
--resource-group <resource-group> \
--scheduler-name <scheduler-name> \
--name <taskhub-name>
Errores de autenticación basados en identidades en Azure
Si la aplicación se ejecuta localmente, pero se produce un error cuando se implementa en Azure, es probable que el problema esté relacionado con la autenticación:
- Compruebe que la identidad administrada está asignada a la aplicación (asignada por el sistema o asignada por el usuario).
- Compruebe que la identidad tiene el rol de colaborador de datos de Durable Task en el recurso del programador o en un centro de tareas específico.
- Asegúrese de que el cadena de conexión usa el valor de
Authenticationcorrecto (ManagedIdentity). En Python, pasa una instanciaDefaultAzureCredential()como parámetrotoken_credentialen lugar de usar una cadena de conexión. - En el caso de las identidades asignadas por el usuario, compruebe que el
ClientIDen el cadena de conexión coincide con el identificador de cliente de la identidad.
Para obtener instrucciones detalladas, consulte Acceso basado en identidades para Durable Task Scheduler.
Problemas de orquestación
La orquestación está bloqueada en el estado "Pendiente"
Una orquestación en estado "Pendiente" indica que está programada, pero un trabajo aún no la ha seleccionado. Compruebe los siguientes elementos:
- El trabajo se está ejecutando. Asegúrese de que el proceso de trabajo esté en funcionamiento y conectado al mismo centro de tareas en el que se programó la orquestación.
- El nombre del centro de tareas coincide. Compruebe que el trabajador y el cliente hacen referencia al mismo nombre del hub de tareas. Una falta de coincidencia hace que el trabajador sondee un centro de tareas diferente.
- Orchestrator está registrado. La función o clase orquestadora a la que se hace referencia al programar debe estar registrada con el trabajador.
Compruebe que la clase de orquestador está registrada con el trabajo durante el inicio. Si usa generadores de origen ([DurableTask] atributo), el registro es automático. De lo contrario, registre manualmente:
builder.Services.AddDurableTaskWorker(builder =>
{
builder.AddTasks(tasks =>
{
tasks.AddOrchestrator<MyOrchestrator>();
tasks.AddActivity<MyActivity>();
});
});
La orquestación está bloqueada en el estado "En ejecución"
Una orquestación bloqueada en "En ejecución" normalmente significa que está esperando una tarea que no se ha completado. Para diagnosticar, abra el panel del Programador de Tareas Duraderas e inspeccione el historial de ejecución de la orquestación. Busque el último evento completado, ya que el siguiente evento de la secuencia es el que está causando el bloqueo.
Causas comunes:
- Actividad no registrada. La orquestación llama a un nombre de actividad que no está registrado con el trabajo. El panel muestra un
TaskScheduledevento sin el correspondienteTaskCompleted. Verifique que el nombre de la actividad coincida entre el código del orquestador y el registro de trabajador (consulte Actividad no encontrada). - Esperando un evento externo. La orquestación llama a
waitForExternalEventy el evento todavía no se desencadena. El panel muestra que se espera un eventoEventRaised, pero no se encuentra. Compruebe el nombre del evento y que el remitente tenga como destino el identificador de instancia de orquestación correcto. - Esperando un temporizador fiable. La orquestación crea un temporizador que aún no ha expirado. El panel muestra un evento
TimerCreated. Espere a que se active el temporizador o compruebe si la duración del temporizador es mayor de lo esperado. - La actividad produce una excepción no controlada. El panel muestra un evento
TaskFailed. Compruebe los detalles del error para el mensaje de excepción y el seguimiento de la pila.
Código de orquestador no determinista
El código de Orchestrator debe ser determinista. El código no determinista provoca errores de reproducción que producen un comportamiento inesperado, bucles infinitos o errores. No use la hora actual, los números aleatorios, los GUID o la E/S (como las llamadas HTTP) directamente en el código del orquestador. Usa las alternativas proporcionadas por el contexto o delega en actividades.
// ❌ Wrong - non-deterministic
var now = DateTime.UtcNow;
var id = Guid.NewGuid();
var data = await httpClient.GetAsync("https://example.com/api");
// ✅ Correct - deterministic
var now = context.CurrentUtcDateTime;
var id = context.NewGuid();
var data = await context.CallActivityAsync<string>("FetchData");
Errores de serialización y deserialización
Los errores de serialización se producen cuando los tipos usados para las entradas, salidas o resultados de actividad de la orquestación no coinciden entre el autor de la llamada y el destinatario. Estos errores pueden aparecer como valores inesperados null, JsonException, o errores de conversión de tipos en el historial de orquestaciones.
Cómo realizar el diagnóstico:
- Abra el panel del Programador de tareas duraderas e inspeccione el historial de orquestación. Mira los campos
InputyResultpara las actividades que fallaron. - Compruebe que el tipo esperado por el orquestador coincide con el tipo devuelto por la actividad. Por ejemplo, si la actividad devuelve un
stringpero el orquestador espera unint, se produce un error en la deserialización. - Compruebe si hay tipos no serializables. Los tipos personalizados que no se pueden serializar en JSON (por ejemplo, tipos con referencias circulares o sin constructor predeterminado) producen errores en modo silencioso o inician excepciones.
Known issue (Java): pasar un String directamente a una actividad puede dar lugar a cadenas entre comillas dobles (por ejemplo, "\"hello\"" en lugar de "hello"). Este comportamiento es un problema conocido. Convierta el resultado explícitamente o use objetos contenedores.
Sugerencia
Use tipos de datos simples (cadenas, números, matrices y objetos sin formato o POJOs/POCOs/dataclasses) para las entradas y salidas de orquestación y actividad. Evite tipos complejos con lógica de serialización personalizada.
Problemas de actividad
Actividad no encontrada
Si una orquestación falla con un error de "actividad no encontrada", significa que el nombre de la actividad registrado con el trabajo no coincide con el nombre utilizado en el código de orquestación.
En .NET, las actividades se pueden registrar por nombre de clase o mediante el atributo [DurableTask] con generadores de origen. Compruebe que la clase de actividad se incluye en el registro de trabajo:
builder.Services.AddDurableTaskWorker(builder =>
{
builder.AddTasks(tasks =>
{
tasks.AddActivity<SayHello>();
});
});
Al llamar a la actividad desde un orquestador, utilice el nombre de la clase:
string result = await context.CallActivityAsync<string>(nameof(SayHello), "Tokyo");
Manejo de fallos de actividad
Cuando una actividad lanza una excepción, el orquestador recibe un TaskFailedException (o su equivalente en el idioma). Capture esta excepción e inspeccione los detalles del error interno para encontrar la causa principal. En C#, use ex.FailureDetails para acceder al tipo de error y el mensaje, y IsCausedBy<T>() para comprobar si hay tipos de excepciones específicos.
Para obtener ejemplos detallados de directivas de control de errores y reintento en cada idioma, consulte Control de errores y reintentos.
Problemas de gRPC
Se superó el límite de tamaño del mensaje gRPC
Si ve un error en RESOURCE_EXHAUSTED o message too large, una entrada o salida de actividad supera el tamaño máximo de mensaje predeterminado de gRPC de 4 MB.
Mitigaciones:
- Reduzca el tamaño de las entradas y salidas. Almacene cargas grandes en el almacenamiento externo, como Azure Blob Storage, y pase solo referencias.
- Divida los resultados grandes de distribución ramificada en lotes más pequeños que se procesen a través de suborquestaciones.
Errores de cancelación de flujos durante el apagado
Al detener un trabajador, puede ver CANCELLED: Cancelled on client errores. Estos errores suelen ser inofensivos y se producen porque la secuencia de gRPC entre el trabajador y el programador se cierra durante el apagado. Los SDK de .NET, Python y Java controlan estos errores internamente.
En JavaScript, el SDK podría lanzar Stream error Error: 1 CANCELLED: Cancelled on client al llamar a worker.stop(). Este error es un problema conocido. Encapsule la llamada de parada en un try-catch si el error afecta a la lógica de cierre:
try {
await worker.stop();
} catch (error) {
// Ignore stream cancellation errors during shutdown
if (!error.message.includes("CANCELLED")) {
throw error;
}
}
Registro y diagnóstico
Configuración del registro detallado
Aumente el detalle del registro para obtener más detalles sobre las operaciones del SDK, incluidas la comunicación a través de gRPC y los eventos de reproducción de orquestación.
En su appsettings.json o archivo de configuración de registro:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.DurableTask": "Debug"
}
}
}
Use registradores seguros para la reproducción para evitar entradas de registro duplicadas durante la reproducción de la orquestación:
public override async Task<string> RunAsync(
TaskOrchestrationContext context, string input)
{
ILogger logger = context.CreateReplaySafeLogger<MyOrchestrator>();
logger.LogInformation("Processing input: {Input}", input);
// ...
}
Integración de Application Insights
En el caso de las aplicaciones de producción, configure Application Insights para recopilar datos de telemetría de la aplicación del SDK de Durable Task. El enfoque de integración depende de la plataforma de hospedaje:
| Plataforma de hospedaje | Instrucciones de instalación |
|---|---|
| Azure Container Apps (Aplicaciones de Contenedores de Azure) | Monitoriza registros en Azure Container Apps con Log Analytics |
| Azure App Service | Habilitación del registro de diagnóstico para aplicaciones en Azure App Service |
| Azure Kubernetes Service | Supervisión de Azure Kubernetes Service |
Para obtener más información sobre los diagnósticos, consulte Diagnósticos en SDK de Durable Task.
Problemas específicos del idioma
C#
Las advertencias del generador de código fuente rompen las compilaciones
Si usa <TreatWarningsAsErrors>true</TreatWarningsAsErrors> en el proyecto, los generadores de origen de Durable Task podrían generar advertencias (CS0419, VSTHRD105) que interrumpen la compilación. Suprima estas advertencias específicas:
<PropertyGroup>
<NoWarn>$(NoWarn);CS0419;VSTHRD105</NoWarn>
</PropertyGroup>
Este problema conocido se está siguiendo en GitHub y se abordará en una próxima versión.
El analizador de Roslyn genera errores en bucles foreach
El analizador Roslyn de Durable Task podría provocar una ArgumentNullException cuando el código lambda del orquestador está dentro de un bucle foreach. Este comportamiento es un problema conocido que no afecta al comportamiento en tiempo de ejecución. Actualice a la versión más reciente del paquete del analizador para obtener la corrección.
Java
Error de permiso denegado de Gradle
En macOS o Linux, la ejecución ./gradlew podría producir un error de "permiso denegado". Corrija este error haciendo que el archivo sea ejecutable:
chmod +x gradlew
OrchestratorBlockedException
OrchestratorBlockedException Se produce cuando el código de orquestador realiza una operación de bloqueo que el SDK detecta como potencialmente no determinista. Esta excepción es una protección para evitar que el código de orquestador infrinjan las restricciones de código del orquestador.
Causas comunes:
- Llamar a una API externa bloqueante en el código del orquestador.
- Usar
Thread.sleep()directamente en lugar dectx.createTimer(). - Realización de entrada/salida de archivos o red en el código del orquestador.
Mueva todas las operaciones de bloqueo o de E/S a actividades.
Python
La política de reintento requiere max_retry_interval
Al configurar un retry_policy en Python, al omitir el parámetro max_retry_interval se produce un error que no indica claramente la causa.
max_retry_intervalEspecifique siempre :
from datetime import timedelta
from durabletask import task
retry_policy = task.RetryPolicy(
max_number_of_attempts=3,
first_retry_interval=timedelta(seconds=5),
max_retry_interval=timedelta(minutes=1), # Required
)
Comportamiento de excepción WhenAllTask
Cuando se usa when_all para ejecutar varias tareas en paralelo, si se produce un error en una o varias tareas, es posible que el comportamiento de la excepción no coincida con las expectativas. Solo se produce la primera excepción y se pueden perder las excepciones de tarea restantes. Inspeccione los resultados de las tareas individuales si necesita información de error completa:
tasks = [ctx.call_activity(process_item, input=item) for item in items]
try:
results = yield task.when_all(tasks)
except TaskFailedError as e:
# Only the first failure is raised
# Check individual tasks for comprehensive error handling
print(f"At least one task failed: {e}")
Obtener soporte técnico
Para preguntas e informes de errores, abra un problema en el repositorio de GitHub para el SDK correspondiente. Al notificar un error, incluya:
- Identificadores de instancia de orquestación afectados
- Intervalo de tiempo en UTC que muestra el problema
- Nombre de aplicación e región de implementación (si procede)
- Versión del SDK y plataforma de hospedaje
- Registros relevantes o mensajes de error
| SDK | Repositorio de GitHub |
|---|---|
| .NET | microsoft/durabletask-dotnet |
| Java | microsoft/durabletask-java |
| JavaScript | microsoft/durabletask-js |
| Python | microsoft/durabletask-python |