Akka - wytłumaczenie na "chłopski rozum"

1

Zastanawia mnie kwestia projektowania aplikacji w Akkce (Scala). Chodzi mi o to, jak najlepiej traktować rolę aktorów. Czy dzielić aplikację w ten sposób, że każdy komponent jest osobnym aktorem, który jest odpowiedzialny za wykonywania jakichś, określonych zadań? Czy każda warstwa (kontrolery, logika, DAO, itd.) ma działać jako osobny aktor? Czy też jeszcze szerzej - każdy aktor to osobny mikroserwis w większym systemie, który porozumiewa się asynchronicznie z innymi? Jakie ma to porównanie z projektowaniem aplikacji znaym np. ze Springa?

Samą idee aktorów i jak działa Akka rozumiem. Chodzi mi o zastosowanie tego np. przy budowaniu aplikacji REST (Akka HTTP). Gdyby ktoś mógł to pokrótce wyjaśnić i (jeśli możliwe) wrzucić np. diagram przykładowej architektury.

1

Kilka użyć, które mają sens:

  • Komunikacja asynchroniczna z stanem mutowalnym
  • Potrzeba skalowalności horyzontalnej (np. routery)
  • location transparency
  • Jakiś system z konkretnym schematem nadzorowania (supervision)

Na pewno jest ich znacznie więcej, to jest to co mi przyszło tak na szybko do głowy. Kilka rzeczy których nie powinno się robić (przynajmniej w moim odczuciu):

2

Samą idee aktorów i jak działa Akka rozumiem. Chodzi mi o zastosowanie tego np. przy budowaniu aplikacji REST (Akka HTTP). Gdyby ktoś mógł to pokrótce wyjaśnić i (jeśli możliwe) wrzucić np. diagram przykładowej architektury.

Akka HTTP nie wymaga tworzenia własnych aktorów w ogóle. Owszem, jest zbudowana na aktorach i oferuje świetną integrację z aktorami, ale ja np stworzyłem w pracy mikroserwis oparty na Akce HTTP, a nie posiadający ani jednego własnego aktora. To kiedy zastosować aktory lub strumienie to decyzja raczej oddzielna od zastosowania Akki HTTP.

Akka HTTP wspiera backpressure, podobnie jak Akka Streams na których jest oparta. Połączenie tych dwóch bibliotek może dać bardzo fajne efekty (sam takie połączenie zrobiłem). Dla przykładu możesz stworzyć serwer HTTP, który:

  • przyjmuje od użytkownika dane, gzipuje je, a potem wysyła na NASa
  • przyjmuje od użytkownika zapytanie, robi zapytanie do bazy danych i strumieniuje je z powrotem do użytkownika
  • generuje dane losowe, bądź np liczby Fibonacciego w nieskończoność

Dzięki temu, że każdą z tych operacji można zaimplementować z obsługą backpressure to będzie miał to backpressure na całej długości. Oznacza to, że generowanie bądź transfer danych zostaną spowolnione jeżeli np CPU nie będzie wyrabiał z gzipowaniem, NAS nie będzie wyrabiał z zapisywaniem, użytkownik nie będzie wyrabiał z odbieraniem danych z bazy bądź danych wygenerowanych, itd Dodatkowo Akka Streams jak sama nazwa wskazuje strumieniują dane, a więc nie generujemy całych danych do wielkiego bufora, tylko generujemy je kawałek po kawałku. Stąd np możemy strumieniowo wysłać 10 GiB danych z bazy przy użyciu 1 megabajtowego bufora, czy też analogicznie przy takim samym buforze gzipować i zapisywać na NASa plik o rozmiarze 10 GiB albo generować losowe dane w nieskończoność (tzn aż klient przerwie ściąganie). Wszystko to bez blokowania wątków, tzn bez setek wątków czekających na IO (bo np 100 użytkowników naraz robi żądania).

* w rzeczywistości zrobienie jednocześnie 100 zapytań do bazy i wczytywanie danych jak najszybciej zwykle wymaga jednak 100 wątków przy użyciu JDBC. JDBC jest synchroniczne, a asynchronicznego standardowego API niestety Oracle jeszcze nie zrobiło. Chociaż z drugiej strony są niestandardowe asynchroniczne API np dla PostgreSQL czy MySQL: https://github.com/mauricio/postgresql-async

1 użytkowników online, w tym zalogowanych: 0, gości: 1