Kategorie
java

Quarkus Event Loop

Być może zastanawiasz się, dlaczego właściwie wydajność nowoczesnych szkieletów, takich jak Quarkus, jest tak wysoka? Czy przypominasz sobie niezwykłe diagramy przedstawiające wojny wydajnościowe między Apachem, a Nginx?

W tym artykule staram się właśnie odpowiedzieć na pytanie, co sprawia, że Quarkus jest tak wydajny. A zatem, czym jest Quarkus Event Loop oraz jak wpływa ona na nasze aplikacje?

Quarkus Event Loop

Ale … to musi trwać długo i blokować wątek

Niektórzy nazywają to … podejściem tradycyjnym. Niektóre operacje rzeczywiście muszą chwilę potrwać i przy okazji zablokować bieżący wątek. Pobieranie złożonych zbiorów z bazy danych, generowanie raportów, czy też synchroniczne zapytania do innych usług zwykle będą trwały więcej niż kilka milisekund. Jeśli nie mamy możliwości zastąpienia ich przez operacje nieblokujące, wówczas należy zastanowić się, jak pogodzić tę sytuację z wykorzystaniem innego mechanizmu.

Tradycyjny serwer aplikacyjny (np. Apache Tomcat) sam z siebie niespecjalnie zawracałby sobie głowę tą sytuacją. Tutaj podejście byłoby proste – więcej żądań do serwera, więc należy dodać więcej wątków je obsługujących. W wyniku czego zwykle skończyłoby się to i tak na zwykłym zwiększeniu moc maszyny produkcyjnej, bo wątki byłyby bardzo nieefektywne.

Tak, czasem musi trwać długo, ale …

W idealnym świecie wszystkie operacje, które wykonuje nasz system trwają krótką chwilę i nie powodują błędów. W świecie rzeczywistym musimy jednak pogodzić się, że tak nie jest.

Z punktu widzenia programisty piszącego oprogramowanie powinniśmy doskonale wiedzieć, które operacje będą korzystały z czasochłonnych i blokujących operacji, a które nie.

Quarkus w swojej warstwie HTTP bazuje na rozwiązaniach opartych o Vert.x i Netty. Oznacza to, że twórcy od samego początku założyli w szkielecie wymaganie pracy z nieblokującymi operacjami.

Efektem tego jest oczekiwanie, że operacje, które mogą być blokujące, zostaną odpowiednio oznaczone. Oznaczenie to ma na celu powiedzenie szkieletowi, że ta konkretna operacja powinno być obsługiwana w inny sposób.

Quarkus Event Loop – jak to działa?

Koncepcja mechanizmu jest całkiem prosta.

W Quarkus wszystkie żądania z warstwy HTTP są obsługiwane przez jedną z pętli zdarzeń (ang. event loop). Sama pętla zdarzeń nie jest niczym innym niż pojedynczym wątkiem IO.

Dlaczego tych pętli jest kilka?

Jest to zwykła optymalizacja. W dobie maszyn wielordzeniowych warto korzystać ze wszystkich dostępnych rdzeni procesora – jedna pętla zdarzeń przetwarzana będzie przez jeden rdzeń.

Architektura Quarkus HTTP  Event Loop
Architektura Quarkus HTTP

Pętla zdarzeń obsługująca dane zlecenie przekieruje je do właściwego fragmentu aplikacji w celu dalszego procesowania.

Jeżeli nasza aplikacja korzystać będzie np. z kontenera serwletów lub JAX-RS w oparciu o RESTEasy, wówczas dana operacja zostanie przetworzona przez oddzielną pulę wątków, tzw. worker threads.

Alternatywnym sposobem tworzenia API opartego o HTTP jest mechanizmu Reactive Routes. W tym przypadku operacje blokujące oznaczać możemy za pomocą Route.HandlerType.BLOCKING

@Route(methods = HttpMethod.POST, path = "/blocking-operation", type = Route.HandlerType.BLOCKING)
public void aLittleLongOperation(RoutingContext rc) {
    // ...
}

Dlaczego Event Loop jest taka ważna?

Gdy chodzi o przetwarzanie dużej liczby zapytań od użytkowników, zawsze jednym z głównych problemów będzie wydajność naszej aplikacji. Czy nasz system poradzi sobie ze zwiększeniem liczby żądań, czy też sobie z tym nie poradzi?

Pętle zdarzeń są wzorcem, który pozwala zoptymalizować w pewnym stopniu wydajność naszych aplikacji. Największy zysk widać oczywiście, gdy nasze serwery obsługują szybkie nieblokujące operacje. Zysk będzie jednak również w innych sytuacjach. Wynika to z tego, że mała liczba wątków będzie generowała dużo mniejsze straty wynikające z konieczności przełączenia kontekstu.

Dlatego w aplikacjach opartych o architekturę Event Loop podstawowym wymogiem będzie nieblokowanie pętli zdarzeń.

Podsumowanie

W artykule przedstawiono koncepcję Quarkus Event Loop, która pozwala temu szkieletowi na uzyskiwanie bardzo dobrych wyników w testach wydajności. Quarkus w tym przypadku został od podstaw zaprojektowany z nastawieniem na przetwarzanie operacji nieblokujących, co wpisuje się w trend nowoczesnych szkieletów dla mikrousług.

Mam nadzieję, że udało mi się dobrze wytłumaczyć ten, skądinąd często postrzegany jako trudny, temat i artykuł będzie dla Ciebie wartościowy.

Jeśli artykuł był dla Ciebie fajny, to podziel się nim z innymi w socialach 😀. Jeśli nie był, to też możesz tak zrobić! 👍

0 0 votes
Article Rating
Subscribe
Powiadom o
guest
0 komentarzy
Inline Feedbacks
View all comments
0
Jestem ciekawy, co myślisz. Dodaj komentarz na dole!x