Obsługa błędów oraz wykonywanie ponownych prób w usłudze Azure Functions
Obsługa błędów w usłudze Azure Functions jest ważna, aby uniknąć utraconych danych, uniknąć pominiętych zdarzeń i monitorować kondycję aplikacji. Jest to również ważny sposób, aby ułatwić zrozumienie zachowań ponawiania prób wyzwalaczy opartych na zdarzeniach.
W tym artykule opisano ogólne strategie obsługi błędów i dostępne strategie ponawiania prób.
Ważne
Obsługa zasad ponawiania prób w wersji zapoznawczej dla niektórych wyzwalaczy została usunięta w grudniu 2022 r. Zasady ponawiania dla obsługiwanych wyzwalaczy są teraz ogólnie dostępne. Aby uzyskać listę rozszerzeń, które obecnie obsługują zasady ponawiania prób, zobacz sekcję Ponowne próby .
Obsługa błędów
Błędy występujące w funkcji platformy Azure mogą pochodzić z:
- Korzystanie z wbudowanych wyzwalaczy i powiązań funkcji.
- Wywołuje interfejsy API bazowych usług platformy Azure.
- Wywołania do punktów końcowych REST.
- Wywołania bibliotek klienckich, pakietów lub interfejsów API innych firm.
Aby uniknąć utraty danych lub nieodebranych komunikatów, ważne jest, aby przećwiczyć dobrą obsługę błędów. W tej tabeli opisano niektóre zalecane rozwiązania dotyczące obsługi błędów i podano linki do dodatkowych informacji.
Zalecenie | Szczegóły |
---|---|
Włącz usługę Application Insights | Usługa Azure Functions integruje się z usługą Application Szczegółowe informacje w celu zbierania danych o błędach, danych wydajności i dzienników środowiska uruchomieniowego. Aby odnaleźć i lepiej zrozumieć błędy występujące w wykonywaniach funkcji, należy użyć Szczegółowe informacje Aplikacji. Aby dowiedzieć się więcej, zobacz Monitorowanie usługi Azure Functions. |
Korzystanie z obsługi błędów ustrukturyzowanych | Przechwytywanie i rejestrowanie błędów ma kluczowe znaczenie dla monitorowania kondycji aplikacji. Najwyższy poziom dowolnego kodu funkcji powinien zawierać blok try/catch. W bloku catch można przechwytywać i rejestrować błędy. Aby uzyskać informacje o błędach, które mogą być zgłaszane przez powiązania, zobacz Binding error codes (Kody błędów powiązań). W zależności od określonej strategii ponawiania można również zgłosić nowy wyjątek, aby ponownie uruchomić funkcję. |
Planowanie strategii ponawiania prób | Kilka rozszerzeń powiązań usługi Functions zapewnia wbudowaną obsługę ponownych prób, a inne umożliwiają definiowanie zasad ponawiania, które są implementowane przez środowisko uruchomieniowe usługi Functions. W przypadku wyzwalaczy, które nie zapewniają zachowania ponawiania prób, należy rozważyć zaimplementowanie własnego schematu ponawiania prób. Aby uzyskać więcej informacji, zobacz Ponowne próby. |
Projektowanie pod kątem idempotentności | Występowanie błędów podczas przetwarzania danych może być problemem dla funkcji, zwłaszcza podczas przetwarzania komunikatów. Ważne jest, aby wziąć pod uwagę, co się stanie, gdy wystąpi błąd i jak uniknąć zduplikowanego przetwarzania. Aby dowiedzieć się więcej, zobacz Projektowanie usługi Azure Functions pod kątem identycznych danych wejściowych. |
Ponowne próby
Istnieją dwa rodzaje ponownych prób dostępnych dla funkcji:
- Wbudowane zachowania ponawiania poszczególnych rozszerzeń wyzwalacza
- Zasady ponawiania próby udostępniane przez środowisko uruchomieniowe usługi Functions
Poniższa tabela wskazuje, które wyzwalacze obsługują ponawianie prób i gdzie skonfigurowano zachowanie ponawiania. Zawiera również linki do dodatkowych informacji o błędach pochodzących z podstawowych usług.
Wyzwalacz/powiązanie | Ponów próbę źródła | Konfigurowanie |
---|---|---|
Azure Cosmos DB | Zasady ponawiania prób | Poziom funkcji |
Blob Storage | Rozszerzenie powiązania | host.json |
Event Grid | Rozszerzenie powiązania | Identyfikator subskrypcji |
Event Hubs | Zasady ponawiania prób | Poziom funkcji |
Kafka | Zasady ponawiania prób | Poziom funkcji |
Queue Storage | Rozszerzenie powiązania | host.json |
RabbitMQ | Rozszerzenie powiązania | Kolejka utraconych listów |
Service Bus | Rozszerzenie powiązania | host.json* |
Czasomierz | Zasady ponawiania prób | Poziom funkcji |
*Wymaga wersji 5.x rozszerzenia usługi Azure Service Bus. W starszych wersjach rozszerzeń zachowania ponawiania są implementowane przez kolejkę utraconych komunikatów usługi Service Bus.
Zasady ponawiania prób
Usługa Azure Functions umożliwia definiowanie zasad ponawiania dla określonych typów wyzwalaczy, które są wymuszane przez środowisko uruchomieniowe. Te typy wyzwalaczy obecnie obsługują zasady ponawiania prób:
Obsługa ponawiania prób jest taka sama zarówno w przypadku modeli programowania w wersji 1, jak i w wersji 2 języka Python.
Zasady ponawiania prób nie są obsługiwane w wersji 1.x środowiska uruchomieniowego usługi Functions.
Zasady ponawiania prób informują środowisko uruchomieniowe o ponownym uruchomieniu nieudanego wykonania do momentu pomyślnego ukończenia lub osiągnięcia maksymalnej liczby ponownych prób.
Zasady ponawiania są oceniane, gdy funkcja wykonywana przez obsługiwany typ wyzwalacza zgłasza nieuchwycony wyjątek. Najlepszym rozwiązaniem jest przechwycenie wszystkich wyjątków w kodzie i wywołanie nowych wyjątków dla błędów, które mają spowodować ponowienie próby.
Ważne
Punkty kontrolne usługi Event Hubs nie są zapisywane dopiero po zakończeniu zasad ponawiania wykonania. Ze względu na to zachowanie postęp na określonej partycji jest wstrzymany do czasu zakończenia przetwarzania bieżącej partii.
Wersja 5.x rozszerzenia usługi Event Hubs obsługuje dodatkowe możliwości ponawiania prób dla interakcji między hostem usługi Functions a centrum zdarzeń. Aby uzyskać więcej informacji, zobacz clientRetryOptions
w dokumentacji usługi Event Hubs host.json.
Strategie dotyczące ponawiania prób
Można skonfigurować dwie strategie ponawiania, które są obsługiwane przez zasady:
Określony czas może upłynąć między poszczególnymi ponownymi próbami.
W przypadku uruchamiania w planie Zużycie opłaty są naliczane tylko za czas wykonywania kodu funkcji. Nie są naliczane opłaty za czas oczekiwania między wykonaniami w jednej z tych strategii ponawiania prób.
Maksymalna liczba ponownych prób
Maksymalną liczbę ponownych prób wykonania funkcji można skonfigurować przed awarią ostateczną. Bieżąca liczba ponownych prób jest przechowywana w pamięci wystąpienia.
Wystąpienie może mieć błąd między ponownymi próbami. Gdy wystąpienie nie powiedzie się podczas zasad ponawiania próby, liczba ponownych prób zostanie utracona. Jeśli wystąpią błędy wystąpień, wyzwalacz usługi Event Hubs może wznowić przetwarzanie i ponowić próbę wsadu w nowym wystąpieniu, a liczba ponownych prób zostanie zresetowana do zera. Wyzwalacz czasomierza nie jest wznawiany w nowym wystąpieniu.
To zachowanie oznacza, że maksymalna liczba ponownych prób jest najlepszym rozwiązaniem. W niektórych rzadkich przypadkach wykonanie może zostać ponowione więcej niż żądana maksymalna liczba razy. W przypadku wyzwalaczy czasomierza ponowne próby mogą być mniejsze niż maksymalna liczba żądana.
Przykłady ponawiania prób
Przykłady są dostępne zarówno dla strategii stałego opóźnienia, jak i wycofywania wykładniczego. Aby wyświetlić przykłady określonej strategii, musisz najpierw wybrać tę strategię na poprzedniej karcie.
Ponawianie prób na poziomie funkcji jest obsługiwane w przypadku następujących pakietów 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}");
}
Właściwości | opis |
---|---|
MaxRetryCount | Wymagany. Maksymalna dozwolona liczba ponownych prób na wykonanie funkcji. -1 oznacza, aby ponowić próbę na czas nieokreślony. |
DelayInterval | Opóźnienie używane między ponownych prób. Określ go jako ciąg w formacie HH:mm:ss . |
Oto przykład zasad ponawiania zdefiniowanych w pliku function.json :
{
"disabled": false,
"bindings": [
{
....
}
],
"retry": {
"strategy": "fixedDelay",
"maxRetryCount": 4,
"delayInterval": "00:00:10"
}
}
Te właściwości można ustawić w definicjach zasad ponawiania prób:
Właściwości | opis |
---|---|
Strategii | Wymagany. Strategia ponawiania, która ma zostać użyta. Prawidłowe wartości to fixedDelay i exponentialBackoff . |
maxRetryCount | Wymagany. Maksymalna dozwolona liczba ponownych prób na wykonanie funkcji. -1 oznacza, aby ponowić próbę na czas nieokreślony. |
delayInterval | Opóźnienie używane między ponownymi próbami podczas korzystania ze fixedDelay strategii. Określ go jako ciąg w formacie HH:mm:ss . |
minimumInterval | Minimalne opóźnienie ponawiania próby podczas korzystania ze exponentialBackoff strategii. Określ go jako ciąg w formacie HH:mm:ss . |
maximumInterval | Maksymalne opóźnienie ponawiania próby podczas korzystania ze exponentialBackoff strategii. Określ go jako ciąg w formacie HH:mm:ss . |
Sposób definiowania zasad ponawiania dla wyzwalacza zależy od wersji Node.js.
Oto przykład funkcji wyzwalacza czasomierza, która używa strategii ponawiania prób o stałym opóźnieniu:
const { app } = require('@azure/functions');
app.timer('timerTriggerWithRetry', {
schedule: '0 */5 * * * *',
retry: {
strategy: 'fixedDelay',
delayInterval: {
seconds: 10,
},
maxRetryCount: 4,
},
handler: (myTimer, context) => {
if (context.retryContext?.retryCount < 2) {
throw new Error('Retry!');
} else {
context.log('Timer function processed request.');
}
},
});
Sposób definiowania zasad ponawiania dla wyzwalacza zależy od wersji Node.js.
Oto przykład funkcji wyzwalacza czasomierza, która używa strategii ponawiania prób o stałym opóźnieniu:
import { app, InvocationContext, Timer } from '@azure/functions';
export async function timerTriggerWithRetry(myTimer: Timer, context: InvocationContext): Promise<void> {
if (context.retryContext?.retryCount < 2) {
throw new Error('Retry!');
} else {
context.log('Timer function processed request.');
}
}
app.timer('timerTriggerWithRetry', {
schedule: '0 */5 * * * *',
retry: {
strategy: 'fixedDelay',
delayInterval: {
seconds: 10,
},
maxRetryCount: 4,
},
handler: timerTriggerWithRetry,
});
Te właściwości można ustawić w definicjach zasad ponawiania prób:
Właściwości | opis |
---|---|
Strategii | Wymagany. Strategia ponawiania, która ma zostać użyta. Prawidłowe wartości to fixedDelay i exponentialBackoff . |
maxRetryCount | Wymagany. Maksymalna dozwolona liczba ponownych prób na wykonanie funkcji. -1 oznacza, aby ponowić próbę na czas nieokreślony. |
delayInterval | Opóźnienie używane między ponownymi próbami podczas korzystania ze fixedDelay strategii. Określ go jako ciąg w formacie HH:mm:ss . |
minimumInterval | Minimalne opóźnienie ponawiania próby podczas korzystania ze exponentialBackoff strategii. Określ go jako ciąg w formacie HH:mm:ss . |
maximumInterval | Maksymalne opóźnienie ponawiania próby podczas korzystania ze exponentialBackoff strategii. Określ go jako ciąg w formacie HH:mm:ss . |
Oto przykład funkcji wyzwalacza czasomierza, która używa strategii ponawiania prób o stałym opóźnieniu:
import logging
from azure.functions import AuthLevel, Context, FunctionApp, TimerRequest
app = FunctionApp(http_auth_level=AuthLevel.ANONYMOUS)
@app.timer_trigger(schedule="*/1 * * * * *", arg_name="mytimer",
run_on_startup=False,
use_monitor=False)
@app.retry(strategy="fixed_delay", max_retry_count="3",
delay_interval="00:00:01")
def mytimer(mytimer: TimerRequest, context: 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.info(
f"Max retries of {context.retry_context.max_retry_count} for "
f"function {context.function_name} has been reached")
else:
raise Exception("This is a retryable exception")
Te właściwości można ustawić w definicjach zasad ponawiania prób:
Właściwości | opis |
---|---|
Strategii | Wymagany. Strategia ponawiania, która ma zostać użyta. Prawidłowe wartości to fixed_delay i exponential_backoff . |
max_retry_count | Wymagany. Maksymalna dozwolona liczba ponownych prób na wykonanie funkcji. -1 oznacza, aby ponowić próbę na czas nieokreślony. |
delay_interval | Opóźnienie używane między ponownymi próbami podczas korzystania ze fixed_delay strategii. Określ go jako ciąg w formacie HH:mm:ss . |
minimum_interval | Minimalne opóźnienie ponawiania próby podczas korzystania ze exponential_backoff strategii. Określ go jako ciąg w formacie HH:mm:ss . |
maximum_interval | Maksymalne opóźnienie ponawiania próby podczas korzystania ze exponential_backoff strategii. Określ go jako ciąg w formacie HH:mm:ss . |
@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());
}
Kody błędów powiązania
Podczas integracji z usługami platformy Azure błędy mogą pochodzić z interfejsów API bazowych usług. Informacje dotyczące błędów specyficznych dla powiązania są dostępne w sekcjach "Wyjątki i kody powrotne" w następujących artykułach:
- Azure Cosmos DB
- Blob Storage
- Event Grid
- Event Hubs
- IoT Hub
- Notification Hubs
- Queue Storage
- Service Bus
- Table Storage