kiedy warto, zeby operacja byla asynchroniczna

0

Kiedy warto wprowadzac w aplikacji komunikacje asynchroniczna? Jakie kryteria powinny byc brane pod uwage?
Kiedy warto brac pod uwage eventy springowe, a kiedy systemy kolejkowe?

Moj przyklad- Mam do wykonania usluge do wysylania powiadomien do uzytkownikow po wypelnieniu formularzu na stronie. Bedzie wysylana 1 wiadomosc przez zewnetrznego klienta e-mail do jednego uzytkownika.

0

Po wypełnieniu formularza odkładasz na kolejkę zdarzenie a oddzielny serwis je konsumuje i generuje na jego podstawie powiadomienie.

1

Kiedy warto wprowadzac w aplikacji komunikacje asynchroniczna?

Trudno opisać wszystkie przypadki, ale np kiedy masz operację wolną i szybką

Moj przyklad- Mam do wykonania usluge do wysylania powiadomien do uzytkownikow po wypelnieniu formularzu na stronie. Bedzie wysylana 1 wiadomosc przez zewnetrznego klienta e-mail do jednego uzytkownika.

Jeśli wypełnienie formularza oraz wysłanie maila są operacjami szybkimi to może nie być powodu żeby wprowadzać operacje asynchroniczne, ale (przykład z życia chociaż nie mojego) jesli w mailu wysyłasz customizowanego PDFa (np bilet na wydarzenie) a zbudowanie tego pdfa trwa dużo czasu dobrze wprowadzić komunikacje asynchroniczną.
Po wprowadzeniu komunikacji asynchronicznej system działał tak że wszyscy klienci na raz kupowali bilety, system odkładał to sobie na kolejkę, a następnie przez noc spokojnie generował bilety. Wszyscy klienci byli zadowoleni bo na rano mieli wygenerowany bilet, a system nie padał za dnia gdy nowi klienci chcieli kupować kolejne bilety

2

@masjav: ale chodzi o jedną aplikacje czy komunikację między z innymi aplikacjami?

1

Kiedy warto brac pod uwage eventy springowe, a kiedy systemy kolejkowe?

Hm, pytanie jest trochę podobne do pytania "kiedy warto trzymać dane w hasmapie, a kiedy w bazie danych"

W zasadzie to już nie znam springa, ale założyłem że eventy springowe to jakaś konstrukcja działająca w obrębie jednej aplikacji. Zaletą tego rozwiązania na pewno będzie lekkość (bo nie trzeba stawiać osobnej aplikacji, bo nie trzeba serializować i przesyłać między aplikacjiami)

Za to kiedy warto używac systemów kolejkowych? Jeszcze pytanie których. Znam trzy Redis, RabbitMQ i Kafka (o ile Kafka to kolejka, zaraz się zacznie). Każdy ma trochę inne właściwości. np Rabbit ma świetną konsolę do monitorowania eventów, za to kafka jest persystentna i mamy dostęp do pełnej historii (o ile oczywiście starczy nam miejsca) i można jej nawet używac jako pokręconej bazy danych

2

W teorii - przeważnie, kiedy nie musisz czekać na zwrotkę, w praktyce - kiedy masz ludzi, którzy to ogarną ;)

EDIT: możesz wybrać jeden z poziomów zaawansowania:
0. Wydzielić konsumenta (mail sendera) do osobnego modułu/kontekstu

  1. Wysyłać powiadomienie podczas zapisu formularza, np. po prostu emitując event Springowy - by default to NIE jest asynchroniczne
  2. Uasynchronicznić konsumenta, tzn. zjadać te eventy w innym wątku, dzięki temu nie blokując logiki zapisu ALBO
    2b. Zapisywać taski do wysłania (taki outbox) i użyć crona (@Scheduled), aby dla każdego taska wyemitować powiadomienie (trochę taka własna Kafka)
  3. Dodać do tego bazę, aby nie gubić tasków
  4. Przejść na zewnętrzna kolejkę
  5. Wydzielić konsumenta do osobnej aplikacji (mikroserwisu).
  6. Zrobić wszystko na serverlessie w cloudzie 😎

Na początek proponuję opcję 3

0

Async popłaca wtedy jak robisz dużo IO ale ono nie jest bottleneckiem. Przykładowo jak masz bottleneck na dysku to async czy sync nic tu nie zmieni. Jak masz bottleneck na tym że np. JVM nie potrafi udźwignąć 20k wątków potrzebnych do obsługi IO ale dysk i sieć nie są obciążone to przejście na async może wiele pomóc.

Pule wątków sporo pomagają w stosunku do klasycznego podejścia wątek na request. Niestety poole dosyć słabo obsługują sytuacje typu spike'i więc trzeba je buforować jakąś kolejką przed.

To tak w telegraficznym skrócie bo to temat rzeka.

2

Może odwróć pytanie do postaci "kiedy warto robić komunikacje synchroniczną?". Będzie prościej odpowiedzieć:
Wtedy kiedy potrzebujesz natychmiastowej informacji, że żądanie dotarło tam gdzie miało dotrzeć i zrobiono z nim to, co należało z nim zrobić. Jeżeli potrzebujesz jedynie informacji, że żądanie zostało przyjęte i kiedyś zostanie obsłużone, to asynchroniczność jest lepszym wyborem. Jak wysyłasz maila, to taka sytuacja nie występuje, potrzebujesz jedynie wiedzieć, że kiedyś, w przyszłości, to zadanie zostanie zrealizowane. Dla mnie prostym wyborem byłaby asynchroniczność.

1

@piotrpo: nie zgodzę się do końca. Czasem jeśli idzie coś przez RAM to nie ma sensu wywoływać czegoś asynchronicznie, bo operacja w tym samym wątku może kosztować więcej z powodu context switchingu. Czy jeśli czyścimy na wskutek eventu domenowego cache typu ConcurrentHashMap to czy asynchroniczność coś daje?

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