Bevezetés a Vert.x-be, amely ma a leggyorsabb Java-keretrendszer

Ha nemrégiben a „legjobb webes keretrendszert” guglizta, akkor a Techempower referenciaértékeibe botlott, ahol több mint háromszáz keretrendszer van rangsorolva. Ott észrevehette, hogy a Vert.x az egyik legmagasabb rangú, ha nem bizonyos mértékig az első.

Szóval beszéljünk róla.

A Vert.x egy poliglot webes keretrendszer, amely a Java, Kotlin, Scala, Ruby és Javascript által támogatott nyelvek között közös funkciókkal rendelkezik. A Vert.x nyelvtől függetlenül a Java virtuális gépen (JVM) működik. Moduláris és könnyű, mikroszolgáltatások fejlesztésére irányul.

A Techempower referenciaértékek az adatok frissítésének, lekérésének és az adatbázisból történő továbbításának teljesítményét mérik. Minél több kérés jelenik meg másodpercenként, annál jobb. Ilyen IO-forgatókönyv esetén, ahol kevés a számítástechnika, minden nem blokkoló keretrendszer előnyt élvez. Az elmúlt években egy ilyen paradigma szinte elválaszthatatlan a Node.js-től, amely egyszálú eseményhurokkal népszerűsítette.

A Vert.x a Node-hoz hasonlóan egyetlen eseményhurkot működtet. De a Vert.x a JVM előnyeit is kihasználja. Míg a Node egyetlen magon fut, a Vert.x egy olyan szálkészletet tart fenn, amelynek mérete megfelel a rendelkezésre álló magok számának. Nagyobb párhuzamossági támogatás mellett a Vert.x nemcsak az IO-ra, hanem a processzor-igényes folyamatokra is alkalmas, amelyek párhuzamos számítást igényelnek.

Az eseményhurkok azonban a történet felét jelentik. A másik felének kevés köze van a Vert.x-hez.

Adatbázishoz való csatlakozáshoz az ügyfélnek csatlakozóillesztőre van szüksége. A Java tartományban az Sql leggyakoribb illesztőprogramja a JDBC. A probléma az, hogy ez az illesztőprogram blokkol. És blokkolja a foglalat szintjén. Egy szál mindig ott ragad, amíg válaszra nem tér vissza.

Mondanom sem kell, hogy az illesztőprogram szűk keresztmetszetet jelentett egy teljesen blokkoló alkalmazás megvalósításában. Szerencsére előrelépés történt (bár nem hivatalos) egy aszinkron illesztőprogramon, több aktív villával, többek között:

  • //github.com/jasync-sql/jasync-sql (Postgres és MySql esetén)
  • //github.com/reactiverse/reactive-pg-client (Postgres)

Az aranyszabály

A Vert.x használatával elég egyszerű dolgozni, és egy http szervert fel lehet hozni néhány kódsorral.

A requestHandler módszer az, ahol az eseményhurok szállítja a kérési eseményt. Mivel a Vert.x véleménytelen, a kezelése szabad stílus. De ne feledje a nem blokkoló szál egyetlen fontos szabályát: ne blokkolja.

Ha párhuzamossággal dolgozunk, számos olyan lehetőség közül meríthetünk, amelyek ma elérhetők, például az Ígéret, a Jövő, az Rx, valamint a Vert.x saját idiomatikus módja. De ahogy az alkalmazás bonyolultabbá válik, önmagában az aszinkron funkciók nem elégek. Szükségünk van a hívások összehangolásának és láncolásának egyszerűségére is, elkerülve a visszahívási poklot, valamint a hibákat kecsesen átadva.

A Scala Future minden fenti feltételt kielégít azzal a további előnnyel, hogy funkcionális programozási elveken alapul. Bár ez a cikk nem vizsgálja meg alaposan a Scala Future-t, megpróbálhatjuk egy egyszerű alkalmazással. Tegyük fel, hogy az alkalmazás egy API-szolgáltatás az azonosítóval rendelkező felhasználó megtalálásához:

Három művelet vesz részt: a kérés paraméterének ellenőrzése, az azonosító érvényes ellenőrzése és az adatok beolvasása. Ezeket a műveleteket egy jövőbe fogjuk burkolni, és a végrehajtást egy „megértésért” struktúrában koordináljuk.

  • Az első lépés az, hogy a kérést összeegyeztessük egy szolgáltatással. A Scala erőteljes mintamegfelelő funkcióval rendelkezik, amelyet erre a célra használhatunk. Itt elfogjuk a „/ user” esetleges említését és átadjuk a szolgáltatásunknak.
  • A következő ennek a szolgáltatásnak a lényege, ahol a jövőnk a megértés sorrendjében van elrendezve. Az első jövőbeni f1 áttekinti a paraméterek ellenőrzését. Kifejezetten szeretnénk lekérni az azonosítót a get kérésből, és bedobni az int-be. (A Scala nem igényel kifejezett visszatérést, ha a visszatérési érték a módszer utolsó sora.) Mint látható, ez a művelet potenciálisan kivételt vethet, mivel az id lehet, hogy nem int vagy nem is elérhető, de ez most rendben van .
  • A második jövőbeli f2 ellenőrzi az id érvényességét. Minden 100-nál alacsonyabb azonosítót blokkolunk, ha kifejezetten felhívjuk a Future.failed-et a saját CustomException-nel. Ellenkező esetben egy üres Jövőt adunk át a Future.unit formában sikeres érvényesítésként.
  • Az utolsó jövőbeli f3 beolvassa a felhasználót az f1 által megadott azonosítóval . Mivel ez csak egy minta, nem igazán csatlakozunk egy adatbázishoz. Csak viszonozunk egy gúnyos húrt.
  • A map futtatja az elrendezést, amely az f3 felhasználói adatait adja, majd kinyomtatja a válaszba.
  • Most, ha a szekvencia bármely részében hiba lép fel, egy Throwable-t adunk át a helyreállításhoz . Itt a típusát egy megfelelő helyreállítási stratégiához igazíthatjuk. Visszatekintve a kódunkba, számos lehetséges hibára számítottunk, például hiányzó azonosító, vagy nem azonos vagy érvénytelen azonosító, amely konkrét kivételeket vet fel. Mindegyiket a handException-ben kezeljük, hibaüzenetet továbbítva az ügyfélnek.

Ez az elrendezés nemcsak aszinkron áramlást biztosít az elejétől a végéig, hanem tiszta megközelítést is biztosít a hibák kezeléséhez. És mivel korszerűsítve van a kezelők között, fontos dolgokra összpontosíthatunk, például az adatbázis lekérdezésére.

Vertikálisok, Eseménybusz és egyéb giccsek

A Vert.x egy olyan egyidejűségi modellt is kínál, amelynek neve verticle, amely hasonlít az Actor rendszerre. (Ha többet szeretne megtudni, keresse fel az Akka Actor útmutatót.) A Verticle izolálja állapotát és viselkedését, hogy szálbiztos környezetet biztosítson. A kommunikáció egyetlen módja egy eseménybuszon keresztül.

A Vert.x eseménybusz azonban megköveteli, hogy üzenetei String vagy JSON legyenek. Ez megnehezíti a tetszőleges, nem POJO objektumok átadását. Nagy teljesítményű rendszerekben pedig a JSON-átalakítás kezelése nem kívánatos, mivel számítási költségeket jelent. Ha IO alkalmazásokat fejleszt, jobb lehet, ha nem használ sem vertikális, sem esemény buszt, mivel ezeknek az alkalmazásoknak alig van szükségük a helyi állapotra.

A Vert.x egyes komponenseivel való együttműködés szintén elég nagy kihívást jelenthet. Megtalálhatja a dokumentáció hiányát, a váratlan viselkedést, sőt a működésképtelenséget is. Lehet, hogy a Vert.x saját ambícióitól szenved, mivel új alkatrészek kifejlesztéséhez sok nyelven kell portolni. Ez nehéz vállalkozás. Ezért lenne a legjobb a maghoz való ragaszkodás.

Ha nyilvános API-t fejleszt, akkor a vertx-core-nak elégnek kell lennie. Ha ez egy webalkalmazás, akkor hozzáadhatja a vertx-webet, amely http paraméterek kezelését és JWT / Session hitelesítést biztosít. Amúgy ez a kettő uralta a viszonyítási alapokat. A vertx-web használatának egyes tesztjeiben némi teljesítménycsökkenés tapasztalható, de mivel úgy tűnik, hogy az optimalizálásból fakadt, a későbbi kiadásokban ezt ki lehet vasalni.