Hogyan egyesíti a Quarkus az imperatív és reaktív programozást

Idén komolyan tervezzük a konténeres témák előmozdítását, Cloud-Native Java és Kubernetes. Ennek a témának a logikus folytatása a Quarkus keretről szóló beszámoló, amelyet már áttekintettünk a Habr-on. A mai cikk nem annyira a „szubatomi szupergyors Java” működésére vonatkozik, hanem arra a perspektívára, amelyet a Quarkus az Enterprise-ba hoz.

Hogyan egyesíti a Quarkus az imperatív és reaktív programozást

A Java és a JVM továbbra is rendkívül népszerű, de a serverless technológiák és a felhőalapú mikroszolgáltatások terén egyre ritkábban használják a Java-t és a JVM más nyelveit, mivel túl sok memóriát foglalnak el és túl lassan töltenek be, így nem alkalmasak a rövid életű konténerekkel való használatra. Szerencsére mostanra ez a helyzet kezd változni a Quarkus-nak köszönhetően.

A szupergyors szubatomi Java új szintre lépett!

42 kiadás, 8 hónap közösségi munka és 177 lenyűgöző fejlesztő – mindez november 2019-ben a Quarkus 1.0 kiadáshoz vezetett, , amely mérföldkő a projekt fejlődésében, és számos klassz funkciót és lehetőséget kínál (többet olvashat aMa arról beszélünk, hogyan egyesíti a Quarkus az imperatív és reaktív programozási modelleket egyetlen reaktív mag köré. Kezdjük egy rövid történeti áttekintéssel, majd részletesen megvizsgáljuk, hogy mi rejlik a Quarkus reaktív magjának dualizmusában, és hogy bejelentés).

-fejlesztők hogyan használhatják ki ezeket az előnyöket. JavaA mikroszolgáltatások

esemény-vezérelt architektúrák,, a serverless és -funkciók – mindez ma, mondhatni, felfutóban van. Az utóbbi időben a felhőalapú architektúrák létrehozása sokkal egyszerűbbé és elérhetőbbé vált, azonban a problémák megmaradtak – különösen a Java-fejlesztők számára. Például a serverless-funkciók és mikroszolgáltatások esetében sürgető szükség van a indítási idő csökkentésére, a memóriahasználat csökkentésére és arra, hogy a fejlesztés kényelmesebbé és élvezetesebbé váljon. Az utóbbi években a Java számos fejlesztést ért el, például a konténerekhez optimalizált ergonomikus funkciókat stb. De a Java normális működésének elérése konténerben továbbra sem egyszerű. Ezért először megvizsgáljuk a Java néhány belső bonyolultságát, amelyek különösen éles hatást gyakorolnak a konténer-alapú Java-alkalmazások fejlesztésekor.-A funkciók mind olyan területek, amelyeket ma már fellendülés jellemez. Az utóbbi időben a felhőalapú architektúrák létrehozása sokkal egyszerűbbé és elérhetőbbé vált, azonban a problémák megmaradtak – különösen a Java-fejlesztők számára. Például a serverless funkciók és mikroszolgáltatások esetében sürgető szükség van a kezdeti indítási idő csökkentésére, a memóriafogyasztás mérséklésére, és arra, hogy a fejlesztési folyamat kényelmesebb és élvezetesebb legyen. Az utóbbi években a Java számos fejlesztést eszközölt, például a konténerek számára kifejlesztett ergonomikai funkciókat és egyebeket. Ennek ellenére a Java megfelelő működtetése konténerben továbbra is nehézségekbe ütközik. Ezért először néhány belső nehézséget fogunk megvizsgálni, amelyek különösen élesebben jelentkeznek a konténeralapú Java-alkalmazások fejlesztése során.

Először nézzük meg a történetet.

Hogyan egyesíti a Quarkus az imperatív és reaktív programozást

Szálak és konténerek

A 8u131-es verziótól kezdve a Java nagyjából elkezdte támogatni a konténereket a funkcionális ergonómiában történt fejlesztések révén. Különösen, mostantól a JVM tudja, hány processzormag fut éppen, és ennek megfelelően tudja optimalizálni a szálpools – általában a fork/join poolokat. Ez kétségtelenül nagyszerű, de tegyük fel, hogy van egy hagyományos webalkalmazásunk, amely HTTP-szervleteket használ, és Tomcat-ban, Jetty-ben és hasonlókban fut. Ennek eredményeként ez az alkalmazás minden egyes kéréshez külön szálat biztosít, és lehetővé teszi, hogy ez a szál blokkolva legyen, amíg I/O műveletekre vár, például adatbázis, fájlok vagy más szolgáltatások elérésekor. Ez azt jelenti, hogy egy ilyen alkalmazás mérete nem a rendelkezésre álló magok számától függ, hanem az egyidejű kérések számától. Ezenkívül ez azt jelenti, hogy a Kubernetes kvóták vagy korlátok a magok számának tekintetében nem sokat segítenek, és a végén throttlinghoz vezet.

Memóriakimerülés

A szálak a memória. És a belső konténer memória korlátozások nem csodaszer. Csak kezdj el növelni az alkalmazások és szálak számát, és előbb-utóbb kritikus növekedéssel találkozol a váltások gyakoriságában, ez pedig teljesítményromláshoz vezet. Ezenkívül, ha az alkalmazás hagyományos mikroszolgáltatás-keretrendszereket használ, vagy adatbázishoz csatlakozik, vagy cache-elést alkalmaz, vagy valahogy további memóriát fogyaszt, akkor nyilvánvalóan szükséged van egy eszközre, amely lehetővé teszi, hogy belenézz a JVM-be, és megnézd, hogyan kezeli azt a memóriát, anélkül, hogy magát a JVM-et megölelnéd (például XX:+UseCGroupMemoryLimitForHeap). És annak ellenére, hogy a Java 9-től kezdve a JVM megtanult cgroups-ot kezelni és ennek megfelelően alkalmazkodni, a memória fenntartása és kezelése továbbra is meglehetősen bonyolult feladat.

Kvóták és korlátok

A Java 11-ben megjelent a CPU-kvóták támogatása (például PreferContainerQuotaForCPUCount). A Kubernetes szintén támogatja a korlátokat és kvótákat. Igen, ennek van értelme, de ha az alkalmazás újra kikerül a kijelölt kvótákból, akkor ismét azon a ponton vagyunk, hogy a méret – a hagyományos Java-alkalmazások esetén – a magok számával, valamint minden kéréshez külön szál biztosításával van meghatározva, így ennek nem sok értelme van.
Ezenkívül, ha kvótákat és limiteket vagy a Kubernetes alapját képező platform horizontális (scale-out) skálázási funkcióit használjuk, a probléma nem oldódik meg magától. Csak több erőforrást költünk el az alapvető probléma megoldására, vagy végül túlfogyasztásra jutunk. Ha ez egy nagy terhelésű rendszer egy nyilvános felhőben, akkor szinte biztos, hogy több erőforrást használunk, mint amennyire valójában szükség van.

És mit lehet kezdeni mindezekkel?

Ha egyszerűen akarjuk, aszinkron és nem blokkoló bemeneti-kimeneti könyvtárakat és keretrendszereket kell használni, mint például a Netty, Vert.x vagy Akka. Ezek sokkal jobban alkalmasak a konténerekben való munkára reaktív természetük miatt. A nem blokkoló bemeneti-kimeneti segítségével ugyanaz a szál több párhuzamos kérés feldolgozására is képes. Amíg egy kérés a bemeneti-kimeneti eredményekre vár, a kezelő szál feloldódik és átvált egy másik kérésre. Amikor a bemeneti-kimeneti eredmények végre megérkeznek, az első kérés feldolgozása folytatódik. A kérések feldolgozásának váltogatásával ugyanazon szál keretein belül csökkenteni lehet a szálak számát és csökkenteni a kérések feldolgozásához szükséges erőforrásokat.

Nem blokkoló bemeneti-kimeneti esetén a magok száma kulcsfontosságú paraméterré válik, mivel ez határozza meg a párhuzamosan végrehajtható bemeneti-kimeneti szálak számát. Ha helyesen használják, ez lehetővé teszi a terhek hatékony elosztását a magok között, és nagyobb terhelések kezelését kevesebb erőforrással.

Hogyan, és ennyi?

Nem, van még valami. A reaktív programozás segít jobban kihasználni az erőforrásokat, de ennek is van költsége. Különösen a kódot a nem blokkolás elvei szerint kell átírni, és kerülni kell a bemeneti-kimeneti szálak blokkolását. Ez egy teljesen más fejlesztési és végrehajtási modell. Bár rengeteg hasznos könyvtár áll rendelkezésre, ennek ellenére ez radikális változást jelent a megszokott gondolkodásmódhoz képest.

Először is, meg kell tanulnod olyan kódot írni, amely aszinkron módon fut. Mihelyt elkezded használni a blokkolás nélküli bemeneti-kimeneti funkciót, egyértelműen meg kell határoznod, hogy mi történjen, amikor válasz érkezik a kérésre. Többé nem blokkolhatod és várhatsz. Ehelyett használhatsz visszahívásokat, reaktív programozást vagy folytonosságot. De ez még nem minden: a blokkolás nélküli bemeneti-kimenet használatához blokkolás nélküli kiszolgálókra és kliensekre van szükséged, és lehetőleg mindenütt. HTTP esetén egyszerű a helyzet, de vannak adatbázisok, fájlrendszerek és még sok egyéb is.

Bár a totális átjárható reaktivitás maximális hatékonyságot biztosít, az ilyen váltásokat nehéz lehet gyakorlatba ültetni. Ezért szükségessé válik a reaktív és imperatív kód ötvözése.

  1. Hatékonyan használni az erőforrásokat a szoftverrendszer legnagyobb terheltségű területein;
  2. Egyszerűbb stílusú kódot alkalmazni a rendszer többi részén.

Bemutatjuk a Quarkus-t

Magában a Quarkus lényegében az imperatív és reaktív modellek egyesítése egyetlen futási környezet keretein belül.

A Quarkus alapját a Vert.x és a Netty képezi, amelyen egy sor reaktív keretrendszer és kiegészítő működik, amelyek segítik a fejlesztőket. A Quarkus nemcsak HTTP-mikroszolgáltatások, hanem eseményvezérelt architektúrák építésére is szolgál. Reaktív természetének köszönhetően rendkívül hatékonyan működik üzenetváltó rendszerekkel (Apache Kafka, AMQP stb.).

A trükk az, hogyan lehet ugyanazt a reaktív motort használni akár imperatív, akár reaktív kódhoz.

Hogyan egyesíti a Quarkus az imperatív és reaktív programozást

A Quarkus kiválóan kezeli ezt. A választás az imperatív és reaktív megközelítés között egyértelmű – mindkettőhöz a reaktív magot használjuk. Nagyon segít a gyors, nem blokkoló kód, amely szinte mindent kezel, ami az eseménykör (event-loop thread, más néven IO thread) átfolyik. De ha klasszikus REST alkalmazásokkal vagy kliensoldali alkalmazásokkal dolgozik, a Quarkus rendelkezik egy imperatív programozási modellel. Például a Quarkus HTTP-támogatása a nem blokkoló és reaktív motor (Eclipse Vert.x és Netty) használatán alapul. Minden HTTP-kérés, amelyet az alkalmazása kap, először az eseménykörön (IO Thread) halad át, majd a kérdések kezeléséért felelős kódhoz kerül. A kéréskezelő kód a célponttól függően külön szál keretein belül hívható meg (ún. worker thread, amely servlet és Jax-RS esetén alkalmazott), vagy az alapvető bemeneti/kimeneti szálat használja (reaktív útvonal, reactive route).

Hogyan egyesíti a Quarkus az imperatív és reaktív programozást

A kérelmezett üzenetátviteli rendszerekhez nem blokkoló klienseket használunk, amelyek a Vert.x motor felett működnek. Így hatékonyan küldheti, fogadhatja és feldolgozhatja az üzeneteket a messaging middleware rendszerekből.

A weboldalon Quarkus.io Összegyűjtöttünk néhány jó útmutatót, amelyek segítenek a Quarkus használatának megkezdésében:

Ezenkívül online gyakorlati anyagokat is készítettünk, amelyek segítenek megismerkedni a reaktív programozás különféle aspektusaival. A tanulásukhoz csupán egy böngésző szükséges, nem szükséges IDE, és egy számítógép sem kötelező. Ezeket az anyagokat itt találhatja: itt.

Hasznos források

10 videoanyag a Quarkusról a téma megértéséhez

Ahogy a weboldalon írják Quarkus.io, Quarkus – ez egy Kubernetes-orientált Java-keretrendszer, amely a GraalVM és az OpenJDK HotSpot köré épült, és a legjobb Java könyvtárakból és szabványokból áll.

A téma megértéséhez összegyűjtöttünk 10 videoanyagot, amelyek különböző aspektusait és példáit mutatják be a Quarkusnak:

1. Bemutatjuk a Quarkust: következő generációs Java keretrendszer Kuberneteshez

Szerzők: Thomas Qvarnstrom és Jason Greene
A Quarkus projekt célja egy Java platform létrehozása Kubernetes és serverless környezetek számára, valamint a reaktív és imperatív programozási modellek integrálása egy egységes futtatási környezetbe, lehetővé téve a fejlesztők számára a rugalmasságot a különböző elosztott alkalmazásarchitektúrákkal való munkában. További információkért nézze meg az alábbi bevezető előadást.

Videó lejátszása

2. Quarkus: szupergyors szubatomikus Java

Szerző: Burr Sutter
A DevNation Live internetes előadása bemutatja, hogyan lehet a Quarkus-t használni vállalati Java alkalmazások, API-k, mikroszolgáltatások és serverless funkciók optimalizálására Kubernetes/OpenShift környezetben, így sokkal kisebbek, gyorsabbak és skálázhatóbbak lesznek.

Videó lejátszása

3. Quarkus és GraalVM: gyorsítsuk fel a Hibernate-et szupersebességekre és csökkentsük szubatomikus méretűre

Szerző: Sanne Grinovero
Az előadásból megtudhatja, hogy jött létre a Quarkus, hogyan működik, és hogyan teszi lehetővé a komplex könyvtárak, mint például a Hibernate ORM, kompatibilitását a GraalVM natív képeivel.

Videó lejátszása

4. Tanuljunk serverless alkalmazásokat fejleszteni

Szerző: Marthen Luther
A lenti videóban bemutatjuk, hogyan lehet egyszerű Java alkalmazást létrehozni Quarkus segítségével, és telepíteni mint serverless alkalmazást Knative-ra.

Videó lejátszása

5. Quarkus: kódoljon örömmel

Szerző: Edson Yanaga
A Quarkus első projektjének létrehozásáról szóló videó útmutatót ad, hogy megértsük, miért szeretik a fejlesztők a Quarkust.

Videó lejátszása

6. Java és konténerek – milyen jövő vár rájuk együtt

Szerző: Mark Little
Ez az előadás bemutatja a Java történelmét, és megmagyarázza, miért a Quarkus a Java jövője.

Videó lejátszása

7. Quarkus: szupergyors szubatomikus Java

Szerző: Dimitris Andreadis
A Quarkus által elismert előnyök áttekintése: egyszerűség, szuper magas sebességek, a legjobb könyvtárak és szabványok.

Videó lejátszása

8. Quarkus és szubatomikus reaktív rendszerek

Szerző: Clement Escoffier
A GraalVM integrációnak köszönhetően a Quarkus szupergyors fejlesztési élményt és szubatomikus futtatási környezetet biztosít. A szerző beszél a Quarkus reaktív oldaláról és arról, hogyan használható reaktív és adatfolyamos alkalmazások létrehozásakor.

Videó lejátszása

9. Quarkus és gyors alkalmazásfejlesztés az Eclipse MicroProfile segítségével

Szerző: John Clingan
Az Eclipse MicroProfile és a Quarkus kombinálásával a fejlesztők teljes funkciójú MicroProfile konténeralkalmazásokat hozhatnak létre, amelyek néhány tizedmásodperc alatt indulnak el. A videó részletesen bemutatja, hogyan lehet MicroProfile konténeralkalmazást kódolni a Kubernetes platformra történő telepítéshez.

Videó lejátszása

10. Java, "Turbo" verzió

Szerző: Markus Biel (Marcus Biel)
A szerző megmutatja, hogyan használjuk a Quarkust superkicsi és szupergyors Java konténerek létrehozására, amelyek valódi áttörést jelenthetnek, különösen serverless környezetekben.

Videó lejátszása


Forrás: habr.com
Megbízható hosting vásárlása weboldalak számára, DDoS védelemmel, VPS VDS szerverek. 🔥 Megbízható webtárhely vásárlása DDoS védelemmel, VPS VDS szerverek | ProHoster