Tratamento de erros e repetições no Azure Functions

O tratamento de erro no Azure Functions é importante para ajudar a evitar perda de dados, evitar perda de eventos e monitorar a integridade do aplicativo. Também é uma maneira importante de ajudá-lo a entender os comportamentos de repetição de gatilhos baseados em evento.

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

Importante

Removeremos o suporte à política de repetição no runtime para gatilhos diferentes de Timer, Kafka e Hubs de Eventos depois que esse recurso fica disponível para o público geral (GA). A versão prévia do suporte da política de repetição para todos os gatilhos que não sejam o Timer e os Hubs de Eventos foi removida em dezembro de 2022. Para obter mais informações, confira a seção Repetições.

Tratando erros

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

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

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

Habilitar o Application Insights

O Azure Functions integra-se ao Application Insights para coletar dados de erro, dados de desempenho e logs de runtime. 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 Azure Functions.

Usar tratamento de erro estruturado

A captura e o registro em log de erros são essenciais para o monitoramento da 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 associação.

Como planeja sua estratégia de repetição

Várias extensões de associações do Functions fornecem suporte interno para repetições. Além disso, o runtime permite definir políticas de repetição para funções disparadas pelo Timer, Kafka e Hubs de Eventos. Para saber mais, consulte Repetições. 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 durante o processamento de dados pode ser um problema para suas funções, especialmente no processamento de mensagens. É importante considerar o que acontece quando o erro ocorre e como evitar o processamento duplicado. Para saber mais, consulte Como projetar o Azure Functions para obter uma entrada idêntica.

Novas tentativas

Existem dois tipos de repetições disponíveis para suas funções:

  • Comportamentos de repetição internos de extensões de gatilho individuais
  • Políticas de repetição fornecidas pelo runtime do Functions

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

Gatilho/associação Origem de repetição Configuração
Azure Cosmos DB Políticas de repetição Nível de função
Armazenamento do Blobs do Azure Extensão de associação host. JSON
Grade de Eventos do Azure Extensão de associação Assinatura 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 associação host. JSON
RabbitMQ Extensão de associação Fila de mensagens mortas
Barramento de Serviço do Azure Extensão de associação Fila de mensagens mortas
Temporizador Políticas de repetição Nível de função
Kafka Políticas de repetição Nível de função

Políticas de repetição

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

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

Uma política de repetição é avaliada quando uma função disparada pelo Timer, Kafka, Hubs de Eventos ou Azure Cosmos DB gera uma exceção não tratada. Como prática recomendada, você deve capturar todas as exceções em seu código e relançar todos os erros que devem resultar 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 da execução tenha sido concluída. Por causa desse comportamento, o progresso na partição específica é pausado até que o lote atual seja concluído.

A extensão dos Hubs de Eventos v5 dá suporte a recursos de repetição adicionais para interações entre o host do Functions e o hub de eventos. Consulte clientRetryOptions na 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 compatíveis com a política:

Um período de tempo especificado pode decorrer entre cada repetição.

Contagens máximas de repetição

Você pode configurar o número máximo de vezes que uma execução da função é repetida antes de uma eventual falha. A contagem de repetições 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 repetição, a contagem de repetição é perdida. Quando há falhas de instância, o gatilho do Hubs de Eventos é capaz de retomar o processamento e repetir o lote em uma nova instância, com a contagem de repetição redefinida para zero. O gatilho do timer não é retomado em uma nova instância.

Esse comportamento significa que a contagem máxima de repetições é um melhor esforço. Em alguns casos raros, uma execução pode ser repetida mais vezes do que o número máximo solicitado. Para gatilhos do Timer, pode haver menos repetições do que o número máximo solicitado.

Exemplos de tentativa

Há suporte para novas tentativas no nível da função 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}");
}
Propriedade Descrição
MaxRetryCount Obrigatórios. O número máximo de repetições permitidas por execução de função. -1 significa repetir indefinidamente.
DelayInterval O atraso usado entre repetições. Especifique-a como uma cadeia de caracteres com o formato: HH:mm:ss.

Esta é a política de repetição no arquivo function.json:

{
    "disabled": false,
    "bindings": [
        {
            ....
        }
    ],
    "retry": {
        "strategy": "fixedDelay",
        "maxRetryCount": 4,
        "delayInterval": "00:00:10"
    }
}
Propriedade function.json Descrição
estratégia Obrigatórios. Usar qual estratégia de repetição. Os valores válidos são fixedDelay ou exponentialBackoff.
maxRetryCount Obrigatórios. O número máximo de repetições permitidas por execução de função. -1 significa repetir indefinidamente.
delayInterval O atraso que será usado entre as repetições quando você está usando uma estratégia fixedDelay. Especifique-a como uma cadeia de caracteres com o formato: HH:mm:ss.
minimumInterval O atraso mínimo de repetição quando você está usando uma estratégia exponentialBackoff. Especifique-a como uma cadeia de caracteres com o formato: HH:mm:ss.
maximumInterval O atraso máximo de repetição quando você está usando a estratégia exponentialBackoff. Especifique-a como uma cadeia de caracteres com o formato: HH:mm:ss.

Aqui está um exemplo do 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 associação

Ao se integrar com serviços do Azure, erros podem ser gerados nas APIs dos serviços subjacentes. As informações relacionadas a erros específicos de associação estão disponíveis nas seções "Exceções e códigos de retorno" dos seguintes artigos:

Próximas etapas