Kako Quarkus kombinuje imperativno i reaktivno programiranje

Ove godine planiramo ozbiljno razvijati kontejnerske teme, Cloud-Native Java и Kubernet. Logičan nastavak ovih tema biće već priča o Quarkusovom okviru razmatrano na Habréu. Današnji članak je manje o dizajnu "subatomske superbrze Jave", a više o obećanju koje Quarkus donosi Enterpriseu.

Kako Quarkus kombinuje imperativno i reaktivno programiranje

Java i JVM su i dalje izuzetno popularni, ali kada se radi sa tehnologijama bez servera i mikroservisima koji su izvorni u oblaku, Java i drugi JVM jezici se koriste sve manje jer zauzimaju previše memorijskog prostora i prespori su za učitavanje, što ih čini slabo pogodan za upotrebu sa kratkotrajnim kontejnerima. Srećom, ova situacija se sada počinje mijenjati zahvaljujući Quarkusu.

Superbrza subatomska Java dostigla je novi nivo!

42 izdanja, 8 mjeseci društvenog rada i 177 nevjerovatnih programera - rezultat svega je bilo izdanje u novembru 2019. Quarkus 1.0, izdanje koje označava važnu prekretnicu u razvoju projekta i nudi puno cool karakteristika i mogućnosti (više o njima možete pročitati u najava).

Danas ćemo vam pokazati kako Quarkus kombinuje imperativne i reaktivne modele programiranja u jedno reaktivno jezgro. Počećemo sa kratkom istorijom, a zatim ulazimo u detalje šta je Quarkusov reaktivni dualizam jezgre i kako Java- Programeri mogu iskoristiti ove pogodnosti.

Mikrousluge, arhitekture vođene događajima и bez servera-funkcije – sve je to danas, kako kažu, u usponu. Nedavno je kreiranje oblako-centričnih arhitektura postalo mnogo lakše i dostupnije, ali problemi ostaju – posebno za Java programere. Na primjer, u slučaju funkcija bez servera i mikrousluga, postoji hitna potreba da se smanji vrijeme pokretanja, smanji potrošnja memorije, a da se njihov razvoj ipak učini praktičnijim i ugodnijim. Java je napravila nekoliko poboljšanja posljednjih godina, kao što je poboljšana ergonomska funkcionalnost za kontejnere i tako dalje. Međutim, natjerati Javu da ispravno radi u kontejneru i dalje je izazov. Dakle, počećemo sa razmatranjem nekih inherentnih složenosti Jave, koje su posebno akutne kada se razvijaju Java aplikacije orijentisane na kontejner.

Prvo, pogledajmo istoriju.

Kako Quarkus kombinuje imperativno i reaktivno programiranje

Potoci i kontejneri

Počevši od verzije 8u131, Java je počela manje-više podržavati kontejnere zbog poboljšanja funkcionalnosti ergonomije. Konkretno, JVM sada zna na koliko procesorskih jezgri radi i može konfigurirati skupove niti – obično fork/join skupove – u skladu s tim. Naravno, ovo je sjajno, ali recimo da imamo tradicionalnu web aplikaciju koja koristi HTTP servlete i radi u Tomcatu, Jettyju, itd. Kao rezultat, ova aplikacija će svakom zahtjevu dati posebnu nit i omogućiti joj da blokira ovu nit dok čeka na I/O operacije, na primjer, kada pristupa bazi podataka, datotekama ili drugim uslugama. Odnosno, veličina takve aplikacije ne ovisi o broju dostupnih jezgara, već o broju istovremenih zahtjeva. Osim toga, to znači da kvote ili ograničenja u Kubernetesu na broj jezgara ovdje neće biti od velike pomoći i stvar će se na kraju završiti gušenjem.

Iscrpljenost pamćenja

Niti su memorija. A ograničenja memorije unutar kontejnera ni u kom slučaju nisu panaceja. Samo počnite povećavati broj aplikacija i niti, i prije ili kasnije ćete naići na kritično povećanje frekvencije prebacivanja i, kao rezultat, degradaciju performansi. Također, ako vaša aplikacija koristi tradicionalne mikroservisne okvire, ili se povezuje na bazu podataka, ili koristi keširanje, ili na drugi način koristi memoriju, očito vam je potreban alat koji vam omogućava da pogledate unutar JVM-a i vidite kako upravlja memorijom bez ubijanja. Sam JVM (na primjer, XX:+UseCGroupMemoryLimitForHeap). Iako je od Jave 9 JVM naučio prihvatiti cgroups i prilagoditi se u skladu s tim, rezerviranje i upravljanje memorijom ostaje prilično složena stvar.

Kvote i ograničenja

Java 11 je uvela podršku za CPU kvote (kao PreferContainerQuotaForCPUCount). Kubernetes takođe nudi podršku za ograničenja i kvote. Da, sve ovo ima smisla, ali ako aplikacija opet premaši dodijeljenu kvotu, opet ćemo završiti s veličinom - kao što je slučaj s tradicionalnim Java aplikacijama - određenom brojem jezgara i dodjelom zasebne niti za svaku zahtev, onda nema smisla u svemu tome.
Osim toga, ako koristite kvote i ograničenja ili funkcije skaliranja platforme koja je u osnovi Kubernetesa, problem se također ne rješava sam od sebe. Jednostavno trošimo više resursa na rješavanje prvobitnog problema ili završimo prekomjerno trošenje. A ako je to sistem visokog opterećenja u javnom javnom oblaku, gotovo sigurno ćemo na kraju koristiti više resursa nego što nam je zaista potrebno.

I šta sa svim ovim?

Jednostavno rečeno, koristite asinkrone i neblokirajuće I/O biblioteke i okvire kao što su Netty, Vert.x ili Akka. Oni su mnogo pogodniji za rad u kontejnerima zbog svoje reaktivne prirode. Zahvaljujući I/O bez blokiranja, ista nit može obraditi više istovremenih zahtjeva. Dok jedan zahtjev čeka na I/O rezultate, obrada niti se oslobađa i preuzima drugi zahtjev. A kada I/O rezultati konačno stignu, obrada prvog zahtjeva se nastavlja. Interleaved obradom zahtjeva unutar iste niti, možete smanjiti ukupan broj niti i smanjiti potrošnju resursa za obradu zahtjeva.

Sa neblokirajućim I/O, broj jezgara postaje ključni parametar jer određuje broj I/O niti koje se mogu izvršavati paralelno. Kada se pravilno koristi, ovo vam omogućava da efektivno rasporedite opterećenje između jezgara i da se nosite sa većim radnim opterećenjem sa manje resursa.

Kako, je li to sve?

Ne, ima još nešto. Reaktivno programiranje pomaže u boljem korištenju resursa, ali ima i svoju cijenu. Konkretno, kod će se morati ponovo napisati u skladu sa principima neblokiranja i izbjegavanja blokiranja I/O niti. A ovo je potpuno drugačiji model razvoja i izvođenja. I iako ovdje ima puno korisnih biblioteka, to je ipak radikalna promjena u uobičajenom načinu razmišljanja.

Prvo, morate naučiti kako pisati kod koji radi asinhrono. Jednom kada počnete koristiti neblokirajući I/O, morate eksplicitno specificirati šta će se dogoditi kada se primi odgovor na zahtjev. Jednostavno blokiranje i čekanje više neće raditi. Umjesto toga, možete proslijediti povratne pozive, koristiti reaktivno programiranje ili nastavak. Ali to nije sve: da biste koristili neblokirajući I/O, potrebni su vam i serveri i klijenti koji ne blokiraju, po mogućnosti svuda. U slučaju HTTP-a sve je jednostavno, ali tu su i baze podataka, sistemi datoteka i još mnogo toga.

I iako ukupna reaktivnost od kraja do kraja maksimizira efikasnost, takav pomak može biti teško shvatljiv u praksi. Stoga, sposobnost kombiniranja reaktivnog i imperativnog koda postaje preduvjet za:

  1. Efikasno koristiti resurse u najopterećenijim područjima softverskog sistema;
  2. Koristite jednostavniji stilski kod u njegovim preostalim dijelovima.

Predstavljamo Quarkusa

Zapravo, ovo je suština Quarkusa - kombinovati reaktivne i imperativne modele unutar jednog okruženja za izvršavanje.

Quarkus je baziran na Vert.x-u i Netty-u, sa nizom reaktivnih okvira i ekstenzija na vrhu koji pomažu programeru. Quarkus je dizajniran za izgradnju ne samo HTTP mikroservisa, već i arhitektura vođenih događajima. Zbog svoje reaktivne prirode, veoma efikasno radi sa sistemima za razmenu poruka (Apache Kafka, AMQP, itd.).

Trik je u tome kako koristiti isti reaktivni motor i za imperativni i za reaktivni kod.

Kako Quarkus kombinuje imperativno i reaktivno programiranje

Quarkus to radi briljantno. Izbor između imperativnog i reaktivnog je očigledan - koristite reaktivno jezgro za oba. Ono u čemu zaista pomaže je brz, neblokirajući kod koji rukuje gotovo svime što prolazi kroz nit petlje događaja, zvanu IO nit. Ali ako imate klasične REST aplikacije ili aplikacije na strani klijenta, Quarkus ima spreman imperativni model programiranja. Na primjer, HTTP podrška u Quarkusu zasnovana je na korištenju neblokirajuće i reaktivne mašine (Eclipse Vert.x i Netty). Svi HTTP zahtjevi koje primi vaša aplikacija prvo se prolaze kroz petlju događaja (IO Thread), a zatim se šalju dijelu koda koji upravlja zahtjevima. U zavisnosti od odredišta, kod za upravljanje zahtjevima može se pozvati unutar zasebne niti (tzv. radna nit, koja se koristi u slučaju servleta i Jax-RS) ili koristiti izvornu I/O nit (reaktivna ruta).

Kako Quarkus kombinuje imperativno i reaktivno programiranje

Sistemski konektori za razmenu poruka koriste klijente koji ne blokiraju rad na vrhu Vert.x motora. Zbog toga možete efikasno slati, primati i obraditi poruke iz međuverskih sistema za razmenu poruka.

Na lokaciji Quarkus.io Evo nekoliko dobrih tutorijala koji će vam pomoći da počnete s Quarkusom:

Napravili smo i online praktične tutorijale kako bismo vas naučili različitim aspektima reaktivnog programiranja samo u pretraživaču, bez potrebe za IDE i bez potrebe za računarom. Možete pronaći ove lekcije ovdje.

Korisni resursi

10 video lekcija o Quarkusu za upoznavanje s ovom temom

Kako kažu na web stranici Quarkus.io, quarkus - je Kubernet-orijentisani Java stek, skrojen za GraalVM i OpenJDK HotSpot i sastavljen od najboljih Java biblioteka i standarda.

Kako bismo vam pomogli da shvatite temu, odabrali smo 10 video tutorijala koji pokrivaju različite aspekte Quarkusa i primjere njegove upotrebe:

1. Predstavljamo Quarkus: Java okvir sljedeće generacije za Kubernetes

Thomas Qvarnstrom i Jason Greene
Cilj Quarkus projekta je kreiranje Java platforme za Kubernetes i okruženja bez servera, te kombiniranje modela reaktivnog i imperativnog programiranja u jedno runtime okruženje tako da programeri mogu fleksibilno mijenjati svoj pristup kada rade sa širokim spektrom distribuiranih arhitektura aplikacija. Saznajte više u uvodnom predavanju u nastavku.

2. Quarkus: Superbrza subatomska Java

Autor: Burr Sutter
Ovaj video tutorijal iz DevNation Live pokazuje kako koristiti Quarkus za optimizaciju poslovnih Java aplikacija, API-ja, mikroservisa i funkcija bez servera u Kubernetes/OpenShift okruženju, čineći ih mnogo manjim, bržim i skalabilnijim.

3. Quarkus i GraalVM: ubrzavanje hibernacije do super brzina i smanjenje na subatomske veličine

Autor: Sanne Grinovero
Iz prezentacije ćete naučiti kako je Quarkus nastao, kako funkcionira i kako vam omogućava da napravite složene biblioteke, kao što je Hibernate ORM, kompatibilne s izvornim GraalVM slikama.

4. Naučite da razvijate aplikacije bez servera

Autor: Martin Luther
Video ispod pokazuje kako da kreirate jednostavnu Java aplikaciju koristeći Quarkus i da je primenite kao aplikaciju bez servera na Knative.

5. Quarkus: Zabavite se kodiranjem

Autor: Edson Yanaga
Video vodič za kreiranje vašeg prvog Quarkus projekta, koji vam omogućava da shvatite zašto Quarkus osvaja srca programera.

6. Java i kontejneri - kakva će biti njihova zajednička budućnost

Objavio Mark Little
Ova prezentacija predstavlja istoriju Jave i objašnjava zašto je Quarkus budućnost Jave.

7. Quarkus: Superbrza subatomska Java

Autor: Dimitris Andreadis
Pregled prednosti Quarkusa koje su dobile priznanje od strane programera: jednostavnost, ultra velike brzine, najbolje biblioteke i standardi.

8. Quarkus i subatomski raketni sistemi

Autor: Clement Escoffier
Kroz integraciju sa GraalVM-om, Quarkus pruža ultra-brzo razvojno iskustvo i subatomsko runtime okruženje. Autor govori o reaktivnoj strani Quarkusa i kako je koristiti za izgradnju reaktivnih i streaming aplikacija.

9. Quarkus i brzi razvoj aplikacija u Eclipse MicroProfile

Autor: John Clingan
Kombinacijom Eclipse MicroProfile i Quarkus, programeri mogu kreirati potpuno opremljene MicroProfile aplikacije u kontejnerima koje se pokreću za desetine milisekundi. Video prikazuje detalje o tome kako kodirati kontejneriziranu MicroProfile aplikaciju za implementaciju na Kubernetes platformi.

10. Java, "Turbo" verzija

Autor: Marcus Biel
Autor pokazuje kako koristiti Quarkus za kreiranje super-male, super-brze Java kontejnere koji omogućavaju pravi proboj, posebno u okruženjima bez servera.



izvor: www.habr.com

Dodajte komentar