Processamento de erros e novas tentativas das Funções do Azure

A manipulação de erros no Azure Functions é importante para ajudá-lo a evitar dados perdidos, evitar eventos perdidos e monitorar a integridade do seu aplicativo. Também é uma maneira importante de ajudá-lo a entender os comportamentos de repetição de gatilhos baseados em eventos.

Este artigo descreve estratégias gerais para tratamento de erros e as estratégias de repetição disponíveis.

Importante

Estamos removendo o suporte à política de repetição no tempo de execução para gatilhos diferentes de Timer, Kafka e Hubs de Eventos depois que esse recurso se tornar disponível ao público (GA). O suporte à política de repetição de visualização para todos os gatilhos que não sejam Timer e Hubs de Eventos foi removido em dezembro de 2022. Para obter mais informações, consulte a seção Repetições .

Processar erros

Os erros que ocorrem em uma função do Azure podem resultar de qualquer um dos seguintes:

  • Uso de gatilhos e associações internos do Azure Functions
  • Chamadas para APIs de serviços subjacentes do Azure
  • Chamadas para pontos de extremidade REST
  • Chamadas para bibliotecas de clientes, pacotes ou APIs de terceiros

Para evitar a perda de dados ou mensagens perdidas, é importante praticar um bom tratamento de erros. Esta seção descreve algumas práticas recomendadas de tratamento de erros e fornece links para mais informações.

Ativar o Application Insights

O Azure Functions integra-se com o Application Insights para coletar dados de erro, dados de desempenho e logs de tempo de execução. Você deve usar o Application Insights para descobrir e entender melhor os erros que ocorrem em suas execuções de função. Para saber mais, consulte Monitorar o Azure Functions.

Usar tratamento estruturado de erros

Capturar e registrar erros é fundamental para monitorar a integridade do seu aplicativo. O nível mais alto de qualquer código de função deve incluir um bloco try/catch. No bloco catch, você pode capturar e registrar erros. Para obter informações sobre quais erros podem ser gerados por associações, consulte Códigos de erro de vinculação.

Planeje sua estratégia de repetição

Várias extensões de vinculação de funções fornecem suporte interno para tentativas. Além disso, o tempo de execução permite definir políticas de repetição para funções acionadas por Timer, Kafka e Hubs de Eventos. Para saber mais, consulte Tentativas. Para gatilhos que não fornecem comportamentos de repetição, convém implementar seu próprio esquema de repetição.

Design para idempotência

A ocorrência de erros quando você está processando dados pode ser um problema para suas funções, especialmente quando você está processando mensagens. É importante considerar o que acontece quando o erro ocorre e como evitar o processamento duplicado. Para saber mais, consulte Projetando o Azure Functions para entradas idênticas.

Tentativas

Há dois tipos de tentativas disponíveis para suas funções:

  • Comportamentos de repetição incorporados de extensões de gatilho individuais
  • Políticas de repetição fornecidas pelo tempo de execução do Functions

A tabela a seguir indica quais gatilhos suportam novas tentativas e onde o comportamento de repetição está configurado. Ele também links para mais informações sobre erros que vêm dos serviços subjacentes.

Gatilho/vinculação Fonte de repetição Configuração
BD do Cosmos para o Azure Políticas de repetição Nível de função
Armazenamento de Blobs do Azure Extensão de vinculação host.json
Grelha de Eventos do Azure Extensão de vinculação Subscrição do evento
Hubs de Eventos do Azure Políticas de repetição Nível de função
Armazenamento de Filas do Azure Extensão de vinculação host.json
RabbitMQ Extensão de vinculação Fila de letra morta
Azure Service Bus Extensão de vinculação Fila de letra morta
Temporizador Políticas de repetição Nível de função
Kafka Políticas de repetição Nível de função

Repetir políticas

A partir da versão 3.x do tempo de execução do Azure Functions, você pode definir políticas de repetição para Timer, Kafka, Hubs de Eventos e gatilhos do Azure Cosmos DB que são impostos pelo tempo de execução do Functions.

A política de repetição informa ao tempo de execução para executar novamente uma execução com falha até que a conclusão bem-sucedida ocorra ou o número máximo de novas tentativas seja atingido.

Uma política de repetição é avaliada quando uma função acionada por Timer, Kafka, Hubs de Eventos ou Azure Cosmos DB gera uma exceção não detetada. Como prática recomendada, você deve capturar todas as exceções em seu código e relançar quaisquer erros que você deseja que resultem em uma nova tentativa.

Importante

Os pontos de verificação dos Hubs de Eventos não serão gravados até que a política de repetição para a execução tenha sido concluída. Devido a esse comportamento, o progresso na partição específica é pausado até que o lote atual tenha terminado.

A extensão Hubs de Eventos v5 oferece suporte a recursos adicionais de repetição para interações entre o host de Funções e o hub de eventos. Consulte a clientRetryOptions seção Hubs de Eventos do arquivo host.json para obter mais informações.

Estratégias de repetição

Você pode configurar duas estratégias de repetição que são suportadas pela política:

É permitido um período de tempo especificado entre cada nova tentativa.

Contagem máxima de tentativas

Você pode configurar o número máximo de vezes que a execução de uma função é repetida antes de uma eventual falha. A contagem de tentativas atual é armazenada na memória da instância.

É possível que uma instância tenha uma falha entre as tentativas de repetição. Quando uma instância falha durante uma política de novas tentativas, a contagem de tentativas é perdida. Quando há falhas de instância, o gatilho de Hubs de Eventos é capaz de retomar o processamento e repetir o lote em uma nova instância, com a contagem de tentativas redefinida para zero. O gatilho do temporizador não é retomado em uma nova instância.

Esse comportamento significa que a contagem máxima de tentativas é um esforço melhor. Em alguns casos raros, uma execução pode ser repetida mais do que o número máximo de vezes solicitado. Para gatilhos de temporizador, as novas tentativas podem ser menores do que o número máximo solicitado.

Exemplos de repetição

As novas tentativas no nível da função são suportadas com os seguintes pacotes NuGet:

[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}");
}
Property Description
MaxRetryCount Obrigatório. O número máximo de tentativas permitidas por execução de função. -1 significa tentar novamente indefinidamente.
DelayInterval O atraso usado entre tentativas. Especifique-o como uma cadeia de caracteres com o formato HH:mm:ss.

Aqui está a política de repetição no arquivo function.json :

{
    "disabled": false,
    "bindings": [
        {
            ....
        }
    ],
    "retry": {
        "strategy": "fixedDelay",
        "maxRetryCount": 4,
        "delayInterval": "00:00:10"
    }
}
function.json propriedade Description
Estratégia Obrigatório. A estratégia de repetição a utilizar. Os valores válidos são fixedDelay ou exponentialBackoff.
maxRetryCount Obrigatório. O número máximo de tentativas permitidas por execução de função. -1 significa tentar novamente indefinidamente.
delayInterval O atraso usado entre novas tentativas quando você está usando uma fixedDelay estratégia. Especifique-o como uma cadeia de caracteres com o formato HH:mm:ss.
mínimoIntervalo O atraso mínimo de repetição quando você está usando uma exponentialBackoff estratégia. Especifique-o como uma cadeia de caracteres com o formato HH:mm:ss.
maximumInterval O atraso máximo de repetição quando você está usando exponentialBackoff a estratégia. Especifique-o como uma cadeia de caracteres com o formato HH:mm:ss.

Aqui está um exemplo de Python que usa o contexto de repetição em uma função:

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 erro de vinculação

Quando você está integrando com os serviços do Azure, os erros podem ter origem nas APIs dos serviços subjacentes. As informações relacionadas a erros específicos de vinculação estão disponíveis nas seções "Exceções e códigos de retorno" dos seguintes artigos:

Próximos passos