Reintentos y control de errores de Azure Functions
El control de los errores en Azure Functions es importante para ayudarle a evitar la pérdida de datos, evitar eventos perdidos y para supervisar el estado de la aplicación. También es una forma importante de ayudarle a comprender los comportamientos de reintento de los desencadenadores basados en eventos.
En este artículo se describen las estrategias generales para el control de errores y las estrategias de reintento disponibles.
Importante
Quitaremos la compatibilidad con la directiva de reintento en el entorno de ejecución para desencadenadores distintos de Temporizador, Kafka y Event Hubs después de que esta característica esté disponible con carácter general (GA). La compatibilidad con la directiva de reintentos de versión preliminar para todos los desencadenadores que no sean Temporizador y Event Hubs se quitó en diciembre de 2022. Para más información, consulte la sección Reintentos.
Control de errores
Los errores que se produzcan en una función de Azure podrían deberse a cualquiera de las siguientes acciones:
- Uso de desencadenadores y enlaces de Azure Functions integrados
- Llamadas a las API de los servicios de Azure subyacentes
- Llamadas a puntos de conexión REST
- Llamadas a bibliotecas de cliente, paquetes o API de terceros
Para evitar la pérdida de datos o mensajes perdidos es importante llevar a cabo un buen control de errores. Esta sección describe algunas prácticas recomendadas para el manejo de errores y proporciona enlaces a más información.
Habilitación de Application Insights
Azure Functions se integra con Application Ideas para recopilar datos de error, datos de rendimiento y registros en tiempo de ejecución. Debería usar Application Insights para detectar y comprender mejor los errores que ocurran en las ejecuciones de funciones. Para más información, consulte Supervisión de Azure Functions.
Uso del control de errores estructurado
La captura y el registro de los errores son fundamentales para supervisar el estado de la aplicación. El nivel superior de cualquier código de función debe incluir un bloque try/catch. En el bloque catch, puede capturar y registrar errores. Para obtener información sobre los errores que pueden generar los enlaces, consulte Códigos de error de enlace.
Planificación la estrategia de reintento
Varias extensiones de enlaces de Functions proporcionan compatibilidad integrada con reintentos. Además, el entorno de ejecución permite definir directivas de reintento para las funciones desencadenadas por Temporizador, Kafka y Event Hubs. Para más información, consulte Reintentos. En el caso de los desencadenadores que no proporcionen comportamientos de reintento, es posible que quiera implementar su propio esquema de reintento.
Diseño para idempotencia
La aparición de errores al procesar datos podría suponer un problema para las funciones, especialmente al procesar mensajes. Es importante tener en cuenta lo que suceda cuando se produzca el error y cómo evitar el procesamiento duplicado. Para obtener más información, vea Diseño de funciones de Azure para entradas idénticas.
Reintentos
Hay dos tipos de reintentos disponibles para sus funciones:
- Comportamientos de reintento integrados de extensiones de desencadenador individuales
- Directivas de reintento proporcionadas por el runtime de Functions
En la tabla siguiente se indica qué desencadenadores admiten reintentos y dónde se configura el comportamiento de reintento. También vincula a más información sobre los errores que proceden de los servicios subyacentes.
Desencadenadores o enlaces | Origen de reintento | Configuración |
---|---|---|
Azure Cosmos DB | Directivas de reintentos | Nivel de función |
Azure Blob Storage | Extensión de enlace | host.json |
Azure Event Grid | Extensión de enlace | Suscripción a eventos |
Azure Event Hubs | Directivas de reintentos | Nivel de función |
Azure Queue Storage | Extensión de enlace | host.json |
RabbitMQ | Extensión de enlace | Cola de mensajes fallidos |
Azure Service Bus | Extensión de enlace | Cola de mensajes fallidos |
Temporizador | Directivas de reintentos | Nivel de función |
Kafka | Directivas de reintentos | Nivel de función |
Directivas de reintentos
A partir de la versión 3.x del entorno de ejecución de Azure Functions, es posible definir directivas de reintento para los desencadenadores de Temporizador. Kafka, Event Hubs y Azure Cosmos DB que aplican el tiempo de ejecución de Functions.
La directiva de reintentos indica al tiempo de ejecución que vuelva a ejecutar una ejecución errónea hasta que se complete correctamente o se alcance el número máximo de reintentos.
Una directiva de reintentos se evalúa cuando una función desencadenada por Temporizador, Kafka, Event Hubs o Azure Cosmos DB genera una excepción no detectada. Como procedimiento recomendado, debería detectar todas las excepciones del código y volver a generar los errores que quiere que vuelva dar lugar a un reintento.
Importante
Los puntos de control de Event Hubs no se escribirán hasta que la directiva de reintentos de la ejecución haya finalizado. Debido a este comportamiento, el progreso de la partición específica se pausa hasta que haya finalizado el lote actual.
La extensión de Event Hubs v5 admite funcionalidades de reintento adicionales para las interacciones entre el host de Functions y el centro de eventos. Consulte clientRetryOptions
en la sección de Event Hubs del archivo host.json para más información.
Estrategia de reintento
Es posible configurar dos estrategias de reintento compatibles con la directiva:
Puede transcurrir un período de tiempo especificado entre cada reintento.
Número máximo de reintentos
Puede configurar el número máximo de veces que se reintenta una ejecución de función antes de que se produzca un error eventual. El número de reintentos actual se almacena en la memoria de la instancia.
Es posible que una instancia de un error entre reintentos. Cuando se produce un error en una instancia durante una directiva de reintentos, se pierde el número de reintentos. Cuando hay errores de instancia, el desencadenador de Event Hubs puede reanudar el procesamiento y reintentar el lote en una nueva instancia, con el número de reintentos restablecido en cero. El desencadenador de temporizador no se reanuda en una nueva instancia.
Este comportamiento significa que el número máximo de reintentos es un mejor esfuerzo. En algunos casos excepcionales, se podría reintentar una ejecución más que el número máximo solicitado de veces. En el caso de los desencadenadores de Temporizador, los reintentos pueden ser menores que el número máximo solicitado.
Ejemplos de reintentos
Los reintentos de nivel de función se admiten con los siguientes paquetes NuGet:
- Microsoft.Azure.Functions.Worker.Sdk>= 1.9.0
- Microsoft.Azure.Functions.Worker.Extensions.EventHubs>= 5.2.0
- Microsoft.Azure.Functions.Worker.Extensions.Kafka>= 3.8.0
- Microsoft.Azure.Functions.Worker.Extensions.Timer>= 4.2.0
[Function(nameof(TimerFunction))]
[FixedDelayRetry(5, "00:00:10")]
public static void Run([TimerTrigger("0 */5 * * * *")] TimerInfo timerInfo,
FunctionContext context)
{
var logger = context.GetLogger(nameof(TimerFunction));
logger.LogInformation($"Function Ran. Next timer schedule = {timerInfo.ScheduleStatus.Next}");
}
Propiedad | Descripción |
---|---|
MaxRetryCount | Necesario. Número máximo de reintentos permitidos por ejecución de función. -1 significa que se reintentará indefinidamente. |
DelayInterval | Retraso que se usa entre reintentos. Especifíquelo como una cadena con el formato HH:mm:ss . |
Esta es la directiva de reintentos del archivo function.json:
{
"disabled": false,
"bindings": [
{
....
}
],
"retry": {
"strategy": "fixedDelay",
"maxRetryCount": 4,
"delayInterval": "00:00:10"
}
}
Propiedad de function.json | Descripción |
---|---|
strategy | Necesario. Estrategia de reintentos que se usará. Los valores válidos son fixedDelay y exponentialBackoff . |
maxRetryCount | Necesario. Número máximo de reintentos permitidos por ejecución de función. -1 significa que se reintentará indefinidamente. |
delayInterval | Retraso que se usa entre reintentos al utilizar la estrategia fixedDelay . Especifíquelo como una cadena con el formato HH:mm:ss . |
minimumInterval | Retraso mínimo entre reintentos al usar la estrategia exponentialBackoff . Especifíquelo como una cadena con el formato HH:mm:ss . |
maximumInterval | Retraso entre reintentos máximo al usar la estrategia exponentialBackoff . Especifíquelo como una cadena con el formato HH:mm:ss . |
Aquí se muestra un ejemplo de Python que usa el contexto de reintento en una función:
import azure.functions
import logging
def main(mytimer: azure.functions.TimerRequest, context: azure.functions.Context) -> None:
logging.info(f'Current retry count: {context.retry_context.retry_count}')
if context.retry_context.retry_count == context.retry_context.max_retry_count:
logging.warn(
f"Max retries of {context.retry_context.max_retry_count} for "
f"function {context.function_name} has been reached")
@FunctionName("TimerTriggerJava1")
@FixedDelayRetry(maxRetryCount = 4, delayInterval = "00:00:10")
public void run(
@TimerTrigger(name = "timerInfo", schedule = "0 */5 * * * *") String timerInfo,
final ExecutionContext context
) {
context.getLogger().info("Java Timer trigger function executed at: " + LocalDateTime.now());
}
Códigos de error de enlace
Cuando se realicen integraciones con los servicios de Azure, podrían originarse errores desde las API de los servicios subyacentes. La información relacionada con errores específicos de enlace está disponible en las secciones "Excepciones y códigos de retorno" de los siguientes artículos:
- Azure Cosmos DB
- Blob Storage
- Event Grid
- Event Hubs
- IoT Hub
- Centros de notificaciones
- Queue Storage
- Service Bus
- Table Storage