Obsługa błędów w nServiceBus (część IV)

W dzisiejszym wpisie pokażę jak nServiceBus radzi sobie z błędami. W środowisku rozproszonych, opartym o kolejki, możliwe jest, że będziemy mieli do czynienia z tymczasowymi błędami. Może to być np. timeout związany z próbą połączenia się z usługą lub deadlock w bazie danych.  Z tego względu, nServiceBus posiada kilkuwarstwowy mechanizm wznawiania wiadomości.

Jeśli przetwarzanie zakończy się błędem, wiadomość nie jest od razu umieszczana w kolejce errors. Najpierw handler jest powtarzany przez określoną liczbę razy (domyślnie 5). Dzięki temu, tymczasowe błędy takie jak deadlock czy timeout mogą zostać zniwelowane. Oczywiście, czasami natychmiastowa ponowna próba jest zbyt szybka. Z tego względu, istnieje druga warstwa mechanizmu recovery. Jeśli pierwsze 5 prób zakończy się niepowodzeniem, wtedy nServiceBus będzie robił przerwy przed kolejnymi próbami i stanowi to drugą warstwę recovery.

Stwórzmy handler, który będzie wyrzucał wyjątek:

class AddPersonHandler:IHandleMessages<AddPerson>
{
   public void Handle(AddPerson message)
   {
       Console.WriteLine(DateTime.Now.ToLongTimeString());
       
       throw new Exception();
   }
}

Na początku, nServiceBus będzie próbował zastosować mechanizm z pierwszej warstwy co poskutkuje pięciokrotnym wykonaniem Handle, jeden po drugim. Jeśli chcemy zmienić wartość domyślną powtórzeń, możemy to w pliku konfiguracyjnym określić:

<MsmqTransportConfig MaxRetries="5" />

Następnie zostanie zastosowana druga warstwa, która ma na celu naprawienie błędów tymczasowych, które jednak mogą potrwać kilka sekund. Domyślne zachowanie można skonfigurować za pomocą:

<SecondLevelRetriesConfig Enabled="true" TimeIncrease="00:00:10" NumberOfRetries="3" />

Widzimy, że będziemy mieli trzy próby, w odstępach 10, 20 oraz 30 sekund (TimeIncrease). Innymi słowy, każda kolejna próba wiążę się z coraz dłuższą przerwą.

Jeśli błąd jest permanentny, wtedy naturalnie żaden mechanizm retry nie zadziała i wiadomość zostanie przekazana do kolejki błędów (errors). Można również skonfigurować, która kolejka będzie zawierała  wiadomości, które nie można było przetworzyć za pomocą:

<MessageForwardingInCaseOfFaultConfig ErrorQueue="error"/>

Możemy zajrzeć do Computer Management i przekonać się, że faktycznie nasza wiadomość została umieszczona w kolejce errors:

image

Należy uważać, na konfiguracje liczby ponowień, ponieważ zbyt wysoka liczba może spowodować spore problemy wydajnościowe. Nie chcemy w końcu w nieskończoność ponawiać wykonania jeśli wiemy, że błędy są permanentne. Metoda w końcu może zawierać skomplikowaną logikę i inne czasochłonne operacje. Każde ponowne wykonanie takiej metody, powoduje zużycie zasobów komputera.

Leave a Reply

Your email address will not be published.