2014-05-21 10 views
7

Obecnie poszukuję strategii Tolerancji usterek i nadzoru w Akka (wersja Java).Tolerancja na awarię Akka Java i ponowne uruchomienie odtwarzacza

na ... http://doc.akka.io/docs/akka/2.3.2/java/fault-tolerance.html i http://doc.akka.io/docs/akka/2.3.2/general/supervision.html#supervision

Kilka pytań:

1) Czy kiedykolwiek używać bloków try/catch w naszych aktorów, gdy wiemy, jakie wyjątki się spodziewać? Dlaczego lub dlaczego nie? Jeśli nie, czy powinniśmy polegać na strategii supervisora, aby skutecznie radzić sobie z wyjątkami, które dziecko może rzucić?

2) Domyślnie, jeśli żaden administrator nie jest jawnie skonfigurowany w aktorze nadrzędnym, wygląda na to, że każdy aktor podrzędny, który zgłasza wyjątek, zostanie domyślnie zrestartowany. Co jeśli żaden z twoich aktorów w twoim systemie nie nosi stanu ... Czy naprawdę powinniśmy robić restart?

3) Co należy zrobić, jeśli aktorzy najwyższego poziomu stworzeni przez system.actorOf (...) zgłaszają wyjątek? W jaki sposób zapewniasz strategię nadzoru poza systemem aktorskim?

4) Załóżmy scenariusz, w którym aktor A ma aktora dziecka B. A teraz powiedzmy, Aktor A prosi aktora B o wykonanie pracy.

Niektóre kod może wyglądać następująco:

Future<Object> future = Patterns.ask(child, message, timeout); 
future.onComplete(new OnComplete<Object>() { 

    @Override 
    public void onComplete(Throwable failure, Object result) throws Throwable { 
      ... handle here  
    } 

teraz ... co, jeśli aktor jakoś zgłasza wyjątek. Domyślnie jest restartowany przez swojego przełożonego. Pytanie brzmi, czy "zamknięcie" onComplete nadal zostanie wykonane w przyszłości, czy też jest skutecznie "wymazywane" przy ponownym uruchomieniu?

5) Załóżmy, że mam hierarchię jako taką: A-> B-> C. Załóżmy też, że nadpisuję preRestart, tak że skutecznie NIE powstrzymuję moich dzieci. W prestarturze on wywołuje funkcję getContext(). ActorOf (B), aw prestarturze B wywołuje funkcję getContext(). ActorOf (C). Jeśli A zgłosi wyjątek, czy w systemie będzie więcej niż jeden aktor B i więcej niż jeden aktor C?

Dzięki!

Odpowiedz

6

To będzie dość długa odpowiedź, ale pozwól mi rozwiązać twoje problemy tak, jak to tylko możliwe.
Ponadto będę polegać na oficjalnej dokumentacji Akka, ponieważ uważam, że Akka jest jednym z najlepiej udokumentowanych projektów i nie chcę wymyślać tego koła. :)

  1. Dobre wprowadzenie/przegląd tolerancji błędu sposób działa w Akce jest [1]. Myślę, że ten artykuł "podsumowuje" całkiem dobrze kilka stron dokumentów Akka. Odpowiadając konkretnie na tę kwestię, myślę, że to zależy: na pewno możesz try/catch wyjątków, aleKernel Pattern stwierdza, że ​​powinieneś "spychać hierarchii aktor" wszystko, co może zawieść (ma to zapobiec lub ograniczyć w miarę możliwości utratę stanu w ramach podmiotów). To powiedziawszy, jeśli masz bardzo specyficzne Exception i wiesz, jak sobie z tym poradzić w ramach przetwarzania wiadomości, nie sądzę, aby istniał jakikolwiek wewnętrzny problem w jej uchwyceniu. W rzeczywistości mogę wymyślić co najmniej jeden konkretny przypadek, w którym chcesz wychwycić wyjątki i obsłużyć je: jeśli Twój aktor odpowiada na Pattern.ask, musisz zawijać wyjątki w Failure, jeśli chcesz, aby dzwoniący był powiadamiany. ([2]).

  2. Zgodnie z zapisem w [3] domyślnym zachowaniem jest w rzeczywistości Restart, ale tylko w przypadku, gdy podczas przetwarzania komunikatu zostanie zgłoszony kod Exception. Zauważ, że ActorInitializationException i ActorKilledException domyślnie kończą dziecko zamiast tego i pamiętają, że każdy Exception wyrzucony w ciągu preStart zostanie zawinięty w ActorInitializationException. Co do tego, czy Restart jest dźwiękową wartością domyślną "w przypadku, gdy nie masz stanu w swoich aktorach" ... Cóż, Aktor jest z definicji abstrakcją, aby bezpiecznie uzyskać dostęp i manipulować stanem w współbieżnym środowisku: jeśli nie masz stanu, możesz równie dobrze używać zamiast sami aktorów. Ogólnie rzecz biorąc, Restart zostało uznane za bezpieczne i uzasadnione domyślne dla typowego przypadku użycia. W twoim konkretnym przypadku (który nie jest typowym przypadkiem użycia dla systemu aktorów), i tak możesz zastąpić domyślną strategię nadzoru.

  3. Najwyższego szczebla aktorzy są na najwyższym poziomie tylko z punktu widzenia "użytkownik". Jak wyjaśniono w [4], dowolny aktor najwyższego poziomu jest tworzony jako dziecko aktora Guardian i ma normalną domyślną strategię nadzoru. Można również zmodyfikować takie domyślne wartości za pomocą właściwości akka.actor.guardian-supervisor-strategy. Pamiętaj też, że powinieneś zawsze projektować systemy, które mają na uwadze hierarchiczną naturę Akki ([5]), dlatego nie używają zbyt dużych aktorów ([6]).

  4. To, czy wywołania zwrotne onComplete będą wywoływane, zależy od tego, kiedy A zakończy się niepowodzeniem. Jeśli nie powiedzie się po wykonaniu polecenia B i odpowiedział na żądanie A, może zostać wykonane. W przeciwnym razie nie będzie. Jest "wymazywany", gdy jest ze starym instancją klasy A.

  5. Jest to nieco mylące, ale będę przyjęto następujące założenia:

    • Kiedy mówisz „A zgłasza wyjątek”, to znaczy w ciągu przetwarzania wiadomości (onReceive)
    • masz pole w Twój aktor, który zapisze refren odesłany przez getContext().actorOf(C).

Szybka odpowiedź brzmi: tak. Biorąc pod uwagę scenariusz, który opisujesz, będzie wiele wystąpień B i C. Nowa instancja o numerze A nie będzie tego jednak wiedzieć. Będzie mieć odniesienie do nowego B i, pośrednio, nowego C. Jest to rozsądne i oczekiwaniami, bo trzeba ręcznie i explicite wyłączone domyślnie kawałek logiki oczyszczania, który obsługuje awarie w hierarchii aktora (zmieniając postRestart): jest teraz odpowiedzialny za oczyszczanie i realizacja preStart opisać robi nie rób tego.

Powiązane problemy