Hogyan kombinálja a Quarkus az imperatív és a reaktív programozást

Idén a konténer témák komoly fejlesztését tervezzük, Cloud-Native Java и Kubernetes. Ezeknek a témáknak logikus folytatása lesz már a Quarkus keretrendszerről szóló történet áttekintette a Habrén. A mai cikk kevésbé a "szubatomi szupergyors Java" tervezéséről szól, hanem inkább arról az ígéretről, amelyet a Quarkus az Enterprise számára hoz.

Hogyan kombinálja a Quarkus az imperatív és a reaktív programozást

A Java és a JVM továbbra is rendkívül népszerű, de amikor szerver nélküli technológiákkal és felhőalapú mikroszolgáltatásokkal dolgozunk, a Java és más JVM nyelvek egyre ritkábban használatosak, mivel túl sok memóriát foglalnak el, és túl lassúak a betöltéshez, ezért gyengén alkalmas rövid élettartamú tartályokhoz. Szerencsére ez a helyzet mostanra kezd megváltozni a Quarkusnak 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 csodálatos fejlesztő – mindennek az eredménye a 2019 novemberi megjelenés Quarkus 1.0, egy olyan kiadás, amely fontos mérföldkövet jelent a projekt fejlesztésében, és rengeteg remek funkciót és képességet kínál (erről bővebben itt olvashat közlemény).

Ma megmutatjuk, hogyan egyesíti a Quarkus az imperatív és a reaktív programozási modelleket egyetlen reaktív magban. Kezdjük egy rövid történettel, majd részletesen kitérünk arra, hogy mi a Quarkus reaktív mag-dualizmusa, és hogyan Jáva-A fejlesztők kihasználhatják ezeket az előnyöket.

Mikroszolgáltatások, eseményvezérelt architektúrák и vagy szerver-funkciók – mindez, ahogy mondani szokták, manapság emelkedik. Az utóbbi időben a felhő-központú architektúrák létrehozása sokkal könnyebbé és elérhetőbbé vált, de a problémák továbbra is fennállnak - különösen a Java fejlesztők számára. Például a szerver nélküli funkciók és mikroszolgáltatások esetében sürgősen csökkenteni kell az indítási időt, csökkenteni kell a memóriafelhasználást, és mégis kényelmesebbé, élvezetesebbé tenni a fejlesztésüket. A Java számos fejlesztést hajtott végre az elmúlt években, például javította a konténerek ergonómiai funkcióit és így tovább. A Java konténerben való megfelelő működésére azonban továbbra is kihívást jelent. Tehát kezdjük azzal, hogy megvizsgáljuk a Java néhány benne rejlő bonyolultságát, amelyek különösen akutak a konténer-orientált Java alkalmazások fejlesztésekor.

Először is nézzük a történelmet.

Hogyan kombinálja a Quarkus az imperatív és a reaktív programozást

Patakok és konténerek

A 8u131-es verziótól kezdve a Java többé-kevésbé támogatni kezdte a konténereket az ergonómiai funkcionalitás fejlesztése miatt. A JVM most már tudja, hogy hány processzormagon fut, és ennek megfelelően konfigurálhatja a szálkészleteket – jellemzően elágazás/csatlakozás készleteket. Ez persze remek, de tegyük fel, hogy van egy hagyományos webes alkalmazásunk, ami HTTP servleteket használ, és Tomcatben, Jettyben stb. Ennek eredményeként ez az alkalmazás minden kérésnek külön szálat ad, és lehetővé teszi, hogy blokkolja ezt a szálat, miközben I/O műveletekre vár, például amikor hozzáfér az adatbázishoz, fájlokhoz vagy más szolgáltatásokhoz. Vagyis 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. Ez ráadásul azt is jelenti, hogy a Kubernetesben a magok számának kvótái vagy korlátai itt nem nagyon fognak segíteni, és az ügy végső soron lefojtással végződik.

Memória kimerültség

A szálak memória. A konténeren belüli memória korlátozása pedig semmiképpen sem csodaszer. Csak kezdje el növelni az alkalmazások és szálak számát, és előbb-utóbb a kapcsolási gyakoriság kritikus növekedésével és ennek eredményeként a teljesítmény romlásával fog találkozni. Továbbá, ha az alkalmazás hagyományos mikroszolgáltatási keretrendszert használ, adatbázishoz csatlakozik, gyorsítótárat használ, vagy más módon elhasználja a memóriát, akkor nyilvánvalóan szüksége van egy olyan eszközre, amely lehetővé teszi, hogy betekintsen a JVM-be, és megtudja, hogyan kezeli a memóriát anélkül, hogy megölné. maga a JVM (például XX:+UseCGroupMemoryLimitForHeap). És annak ellenére, hogy a Java 9 óta a JVM megtanulta elfogadni a cgroupokat és ennek megfelelően alkalmazkodni, a memória lefoglalása és kezelése továbbra is meglehetősen összetett kérdés.

Kvóták és korlátok

A Java 11 bevezette a CPU-kvóták támogatását (mint például a PreferContainerQuotaForCPUCount). A Kubernetes támogatja a korlátokat és a kvótákat is. Igen, ennek az egésznek van értelme, de ha az alkalmazás ismét túllépi a lefoglalt kvótát, akkor ismét a méretet kapjuk – mint a hagyományos Java alkalmazásoknál –, amelyet a magok száma határoz meg, és mindegyikhez külön szálat kell kiosztani. kérésére, akkor ennek az egésznek nincs sok értelme.
Ezenkívül, ha kvótákat és korlátokat vagy a Kubernetes alapjául szolgáló platform kibővítési funkcióit használja, a probléma szintén nem oldódik meg magától. Egyszerűen több erőforrást költünk az eredeti probléma megoldására, vagy túlköltenénk. És ha ez egy nagy terhelésű rendszer egy nyilvános nyilvános felhőben, akkor szinte biztosan több erőforrást használunk fel, mint amennyire valóban szükségünk van.

És mit kell kezdeni ezzel az egésszel?

Egyszerűen fogalmazva: használjon aszinkron és nem blokkoló I/O könyvtárakat és keretrendszereket, mint például a Netty, Vert.x vagy Akka. Reaktív természetük miatt sokkal jobban alkalmasak konténerekben való munkára. A nem blokkoló I/O-nak köszönhetően ugyanaz a szál több egyidejű kérést is képes feldolgozni. Amíg az egyik kérés az I/O eredményekre vár, az azt feldolgozó szál felszabadul, és egy másik kérelem veszi át. És amikor az I/O eredmények végre megérkeznek, az első kérés feldolgozása folytatódik. Az ugyanazon szálon belüli kérelmek átlapolt feldolgozásával csökkentheti a szálak teljes számát, és csökkentheti a kérések feldolgozásához szükséges erőforrás-felhasználást.

A nem blokkoló I/O esetén a magok száma kulcsparaméterré válik, mert ez határozza meg a párhuzamosan végrehajtható I/O szálak számát. Helyes használat esetén ez lehetővé teszi a terhelés hatékony elosztását a magok között, és kevesebb erőforrással kezelheti a nagyobb munkaterhelést.

Hogyan, ennyi?

Nem, van még valami. A reaktív programozás segít az erőforrások jobb kihasználásában, de ennek ára is van. Különösen a kódot kell átírni a blokkolásmentesség elve szerint, és kerülni kell az I/O szálak blokkolását. És ez egy teljesen más fejlesztési és végrehajtási modell. És bár sok hasznos könyvtár található itt, ez mégis gyökeres változás a megszokott gondolkodásmódban.

Először is meg kell tanulnia, hogyan írjon aszinkron módon futó kódot. Ha elkezdi használni a nem blokkoló I/O-t, kifejezetten meg kell adnia, hogy mi történjen, amikor egy kérésre válasz érkezik. Az egyszerű blokkolás és várakozás többé nem fog működni. Ehelyett átadhat visszahívásokat, használhat reaktív programozást vagy folytatást. De ez még nem minden: a nem blokkoló I/O használatához szükség van nem blokkoló szerverekre és kliensekre is, lehetőleg mindenhol. A HTTP esetében minden egyszerű, de vannak adatbázisok, fájlrendszerek és még sok más is.

És bár a teljes végpontok közötti reaktivitás maximalizálja a hatékonyságot, egy ilyen eltolódást a gyakorlatban nehéz lehet megbirkózni. Ezért a reaktív és a kötelező kód kombinálásának képessége előfeltétele annak, hogy:

  1. Hatékonyan használja az erőforrásokat a szoftverrendszer legterheltebb területein;
  2. Használjon egyszerűbb stíluskódot a többi részében.

Bemutatkozik a Quarkus

Valójában ez a Quarkus lényege – a reaktív és kötelező modellek egyetlen futási környezetben való kombinálása.

A Quarkus a Vert.x-en és a Netty-n alapul, és a tetején számos reaktív keretrendszer és bővítmény segíti a fejlesztőt. A Quarkust nemcsak HTTP mikroszolgáltatások, hanem eseményvezérelt architektúrák építésére is tervezték. Reaktív jellege miatt nagyon hatékonyan működik üzenetküldő rendszerekkel (Apache Kafka, AMQP stb.).

A trükk az, hogy hogyan lehet ugyanazt a reaktív motort használni mind a kötelező, mind a reaktív kódhoz.

Hogyan kombinálja a Quarkus az imperatív és a reaktív programozást

Quarkus ezt zseniálisan csinálja. A kötelező és a reaktív közötti választás nyilvánvaló – mindkettőhöz használjon reaktív kernelt. Amiben igazán segít, az a gyors, nem blokkoló kód, amely szinte mindent kezel, ami az eseményhurok szálon, más néven IO szálon megy át. De ha klasszikus REST vagy kliensoldali alkalmazásai vannak, a Quarkusnak készen áll egy elengedhetetlen programozási modellje. Például a Quarkus HTTP-támogatása egy nem blokkoló és reaktív motor (Eclipse Vert.x és Netty) használatán alapul. Az alkalmazás által kapott összes HTTP-kérelem először egy eseményhurokon (IO Thread) kerül át, majd elküldésre kerül a kód azon részére, amely a kéréseket kezeli. A céltól függően a kéréskezelési kód meghívható egy külön szálon belül (az úgynevezett worker szálon, amelyet servletek és Jax-RS esetén használnak), vagy használhatja a forrás I/O szálat (reaktív útvonal).

Hogyan kombinálja a Quarkus az imperatív és a reaktív programozást

Az üzenetküldő rendszer csatlakozói a Vert.x motor tetején futó, nem blokkoló ügyfeleket használnak. Ezért hatékonyan küldhet, fogadhat és dolgozhat fel üzeneteket az üzenetküldő köztes szoftverrendszerekből.

Az oldal Quarkus.io Íme néhány jó oktatóanyag, amelyek segítenek a Quarkus használatának megkezdésében:

Online gyakorlati oktatóanyagokat is készítettünk, amelyek segítségével megtaníthatjuk a reaktív programozás különféle aspektusait, csupán egy böngészőben, nincs szükség IDE-re és számítógépre sem. Ezeket a leckéket megtalálhatod itt.

Hasznos források

10 videó lecke a Quarkuson a téma megismeréséhez

Ahogy a honlapon mondják Quarkus.io, quarkus - Van Kubernetes-orientált Java verem, a GraalVM és az OpenJDK HotSpot számára szabva, és a legjobb Java könyvtárakból és szabványokból összeállítva.

A téma megértésének elősegítése érdekében kiválasztottunk 10 oktatóvideót, amelyek a Quarkus különféle aspektusait és felhasználási példáit ismertetik:

1. Bemutatkozik a Quarkus: The Next Generation Java Framework for Kubernetes

Írta: Thomas Qvarnstrom és Jason Greene
A Quarkus projekt célja Java platform létrehozása Kubernetes és kiszolgáló nélküli környezetek számára, valamint a reaktív és kötelező programozási modellek egyetlen futási környezetbe való ötvözése, hogy a fejlesztők rugalmasan variálhassák megközelítésüket az elosztott alkalmazásarchitektúrák széles skálájával való munka során. Tudjon meg többet az alábbi bevezető előadásból.

2. Quarkus: Szupergyors szubatomi Java

Szerző: Burr Sutter
A DevNation Live oktatóvideója bemutatja, hogyan használható a Quarkus vállalati Java-alkalmazások, API-k, mikroszolgáltatások és kiszolgáló nélküli funkciók optimalizálására Kubernetes/OpenShift környezetben, így sokkal kisebbek, gyorsabbak és skálázhatóak.

3. Quarkus és GraalVM: a hibernálás szuper sebességre gyorsítása és szubatomi méretűre zsugorítása

Szerző: Sanne Grinovero
A prezentációból megtudhatja, hogyan jött létre a Quarkus, hogyan működik, és hogyan teszi lehetővé az összetett könyvtárak, például a Hibernate ORM, kompatibilissé tételét a natív GraalVM-képekkel.

4. Tanuljon meg szerver nélküli alkalmazásokat fejleszteni

Szerző: Luther Márton
Az alábbi videó bemutatja, hogyan hozhat létre egy egyszerű Java-alkalmazást a Quarkus segítségével, és hogyan helyezheti üzembe kiszolgáló nélküli alkalmazásként a Knative-on.

5. Quarkus: Jó szórakozást a kódoláshoz

Szerző: Edson Yanaga
Útmutató az első Quarkus projekt elkészítéséhez, amely lehetővé teszi, hogy megértse, miért hódítja meg a Quarkus a fejlesztők szívét.

6. Java és konténerek – mi lesz a közös jövőjük

Írta: Mark Little
Ez az előadás bemutatja a Java történetét, és elmagyarázza, miért a Quarkus a Java jövője.

7. Quarkus: Szupergyors szubatomi Java

Szerző: Dimitris Andreadis
A Quarkus fejlesztők által elismert előnyeinek áttekintése: egyszerűség, rendkívül nagy sebesség, a legjobb könyvtárak és szabványok.

8. Kvarkuszok és szubatomi rakétarendszerek

Szerző: Clement Escoffier
A GraalVM-mel való integráció révén a Quarkus rendkívül gyors fejlesztési élményt és szubatomi futási környezetet biztosít. A szerző a Quarkus reaktív oldaláról beszél, és arról, hogyan használható fel reaktív és streaming alkalmazások létrehozására.

9. Quarkus és gyors alkalmazásfejlesztés az Eclipse MicroProfile-ban

Szerző: John Clingan
Az Eclipse MicroProfile és a Quarkus kombinálásával a fejlesztők teljes értékű konténeres MicroProfile alkalmazásokat hozhatnak létre, amelyek több tíz ezredmásodperc alatt indulnak el. A videó részletesen bemutatja, hogyan kell kódolni egy konténeres MicroProfile alkalmazást a Kubernetes platformon történő telepítéshez.

10. Java, "Turbo" verzió

Szerző: Marcus Biel
A szerző bemutatja, hogyan használható a Quarkus szuperkicsi, szupergyors Java konténerek létrehozására, amelyek valódi áttörést tesznek lehetővé, különösen szerver nélküli környezetben.



Forrás: will.com

Hozzászólás