Kako Quarkus kombinira imperativno i reaktivno programiranje

Ove godine planiramo ozbiljno razviti teme kontejnera, Java izvorna u oblaku и Kubernetes. Logičan nastavak ovih tema bit će već priča o Quarkus frameworku razmatran 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 kombinira imperativno i reaktivno programiranje

Java i JVM i dalje su iznimno popularni, ali kada se radi s tehnologijama bez poslužitelja i mikroservisima izvornim u oblaku, Java i drugi JVM jezici koriste se sve manje jer zauzimaju previše memorijskog prostora i presporo se učitavaju, što ih čini slabo prikladan za korištenje s kratkotrajnim spremnicima. Srećom, ova se situacija sada počinje mijenjati zahvaljujući Quarkusu.

Superbrza subatomska Java dosegla je novu razinu!

42 izdanja, 8 mjeseci rada u zajednici i 177 nevjerojatnih programera - rezultat svega je izdanje u studenom 2019. Quarkus 1.0, izdanje koje označava važnu prekretnicu u razvoju projekta i nudi mnogo cool značajki i mogućnosti (više o njima možete pročitati u Obavijest).

Danas ćemo vam pokazati kako Quarkus kombinira modele imperativnog i reaktivnog programiranja u jednu reaktivnu jezgru. Počet ćemo s kratkom poviješću, a zatim ići u detalje o tome što je Quarkusov dualizam reaktivne jezgre i kako Java- Programeri mogu iskoristiti ove pogodnosti.

Mikroservisi, arhitekture vođene događajima и serverless-funkcije – sve je to danas, kako kažu, u porastu. Nedavno je stvaranje arhitektura usmjerenih na oblak postalo mnogo lakše i pristupačnije, ali problemi ostaju - posebno za Java programere. Na primjer, u slučaju funkcija i mikrousluga bez poslužitelja, hitno je potrebno smanjiti vrijeme pokretanja, smanjiti potrošnju memorije, a njihov razvoj ipak učiniti praktičnijim i ugodnijim. Java je napravila nekoliko poboljšanja posljednjih godina, kao što je poboljšana ergonomska funkcionalnost za spremnike i tako dalje. Međutim, natjerati Javu da ispravno radi u spremniku i dalje je izazov. Stoga ćemo započeti promatranjem nekih inherentnih složenosti Jave, koje su osobito akutne pri razvoju Java aplikacija orijentiranih na spremnike.

Prvo, pogledajmo povijest.

Kako Quarkus kombinira imperativno i reaktivno programiranje

Potoci i spremnici

Počevši od verzije 8u131, Java je počela više-manje podržavati spremnike zbog poboljšanja ergonomske funkcionalnosti. Konkretno, JVM sada zna na koliko procesorskih jezgri radi i može konfigurirati skupove niti—obično skupove fork/join—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 toga, ova aplikacija će svakom zahtjevu dati zasebnu nit i dopustiti joj da blokira ovu nit dok čeka I/O operacije, na primjer, kada se pristupa bazi podataka, datotekama ili drugim uslugama. Odnosno, veličina takve aplikacije ne ovisi o broju dostupnih jezgri, već o broju istodobnih zahtjeva. Osim toga, to znači da kvote ili limiti u Kubernetesu na broj jezgri tu neće biti od velike pomoći i stvar će u konačnici završiti na throttlingu.

Iscrpljenost pamćenja

Niti su memorija. A ograničenja memorije unutar spremnika nipošto nisu lijek za sve. Samo počnite povećavati broj aplikacija i niti, i prije ili kasnije naići ćete na kritično povećanje učestalosti prebacivanja i, kao rezultat toga, degradaciju performansi. Također, ako vaša aplikacija koristi tradicionalne okvire mikroservisa, ili se povezuje s bazom podataka, ili koristi predmemoriju, ili na neki drugi način koristi memoriju, očito vam je potreban alat koji vam omogućuje da pogledate unutar JVM-a i vidite kako upravlja memorijom bez da je ubije. Sam JVM (na primjer, XX:+UseCGroupMemoryLimitForHeap). I iako je, od Jave 9, JVM naučio prihvaćati cgroups i prilagođavati se u skladu s tim, rezerviranje i upravljanje memorijom ostaje prilično složena stvar.

Kvote i ograničenja

Java 11 uvela je podršku za CPU kvote (poput PreferContainerQuotaForCPUCount). Kubernetes također nudi podršku za ograničenja i kvote. Da, sve ovo ima smisla, ali ako aplikacija ponovno premaši dodijeljenu kvotu, opet završavamo s veličinom - kao što je slučaj s tradicionalnim Java aplikacijama - određenom brojem jezgri i s dodjelom zasebne niti za svaku zahtjev, onda sve ovo nema malo smisla.
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 izvornog problema ili na kraju trošimo prekomjerno. A ako se radi o visokoopterećenom sustavu u javnom javnom oblaku, gotovo sigurno na kraju koristimo više resursa nego što nam je stvarno potrebno.

I što učiniti sa svim tim?

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

Uz neblokirajući I/O, broj jezgri postaje ključni parametar jer određuje broj I/O niti koje se mogu izvoditi paralelno. Kada se pravilno koristi, to vam omogućuje učinkovitu raspodjelu opterećenja između jezgri i rukovanje većim radnim opterećenjima s manje resursa.

Kako, je li to sve?

Ne, postoji nešto drugo. Reaktivno programiranje pomaže boljem korištenju resursa, ali ima i svoju cijenu. Konkretno, kod će se morati ponovno napisati u skladu s načelima neblokiranja i izbjegavanja blokiranja I/O niti. A ovo je potpuno drugačiji model razvoja i izvedbe. I premda ovdje ima puno korisnih biblioteka, ipak je riječ o radikalnoj promjeni uobičajenog načina razmišljanja.

Prvo morate naučiti kako napisati kod koji radi asinkrono. Nakon što počnete koristiti neblokirajući I/O, morate eksplicitno odrediti što bi se trebalo dogoditi kada se primi odgovor na zahtjev. Jednostavno blokiranje i čekanje više neće funkcionirati. 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 neblokirajući poslužitelji i klijenti, po mogućnosti posvuda. U slučaju HTTP-a sve je jednostavno, ali tu su i baze podataka, datotečni sustavi i još mnogo toga.

I premda ukupna reaktivnost s kraja na kraj maksimizira učinkovitost, takav pomak u praksi može biti teško podnošljiv. Stoga sposobnost kombiniranja reaktivnog i imperativnog koda postaje preduvjet kako bi se:

  1. Učinkovito koristiti resurse u najopterećenijim područjima softverskog sustava;
  2. Koristite jednostavniji kod stila u njegovim preostalim dijelovima.

Predstavljamo Quarkus

Zapravo, to je bit Quarkusa - kombinirati reaktivne i imperativne modele unutar jednog runtime okruženja.

Quarkus se temelji na Vert.x i Netty, s nizom reaktivnih okvira i proširenja 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, vrlo učinkovito radi sa sustavima za razmjenu poruka (Apache Kafka, AMQP, itd.).

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

Kako Quarkus kombinira imperativno i reaktivno programiranje

Quarkus to radi briljantno. Izbor između imperativnog i reaktivnog je očit - koristite reaktivni kernel za oba. Ono u čemu stvarno pomaže je brz kod bez blokiranja koji obrađuje gotovo sve što prolazi kroz nit petlje događaja, poznatu i kao IO nit. Ali ako imate klasični REST ili aplikacije na strani klijenta, Quarkus ima spreman imperativni model programiranja. Na primjer, HTTP podrška u Quarkusu temelji se na korištenju neblokirajućeg i reaktivnog motora (Eclipse Vert.x i Netty). Svi HTTP zahtjevi koje primi vaša aplikacija prvo prolaze kroz petlju događaja (IO nit), a zatim se šalju dijelu koda koji upravlja zahtjevima. Ovisno o odredištu, kod za upravljanje zahtjevima može se pozvati unutar zasebne niti (tzv. radna nit, koja se koristi u slučaju servleta i Jax-RS-a) ili koristiti izvornu I/O nit (reaktivna ruta).

Kako Quarkus kombinira imperativno i reaktivno programiranje

Konektori sustava za razmjenu poruka koriste neblokirajuće klijente koji rade na vrhu Vert.x motora. Stoga možete učinkovito slati, primati i obrađivati ​​poruke iz sustava srednjeg softvera za razmjenu poruka.

Stranica Quarkus.io Evo nekoliko dobrih vodiča koji će vam pomoći da počnete s Quarkusom:

Također smo kreirali online praktične poduke kako bismo vas naučili razne aspekte reaktivnog programiranja samo u pregledniku, bez IDE-a i bez računala. Možete pronaći ove lekcije здесь.

Korisni resursi

10 video lekcija o Quarkusu za upoznavanje s temom

Kako kažu na web stranici Quarkus.io, kvarkus - ovo je Kubernetes-orijentirani Java stack, prilagođen za GraalVM i OpenJDK HotSpot i sastavljen od najboljih Java biblioteka i standarda.

Kako bismo vam pomogli razumjeti 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 projekta Quarkus je stvoriti Java platformu za Kubernetes i okruženja bez poslužitelja, te kombinirati reaktivne i imperativne programske modele u jedno okruženje za izvođenje tako da programeri mogu fleksibilno mijenjati svoj pristup pri radu sa širokim rasponom arhitektura distribuiranih aplikacija. Više doznajte u uvodnom predavanju u nastavku.

2. Quarkus: Superbrza subatomska Java

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

3. Quarkus i GraalVM: ubrzavanje Hibernatea do super brzina i njegovo smanjivanje na subatomske veličine

Autor: Sanne Grinovero
Iz prezentacije ćete saznati kako je Quarkus nastao, kako radi i kako vam omogućuje da napravite složene biblioteke, poput Hibernate ORM-a, kompatibilne s izvornim GraalVM slikama.

4. Naučite razvijati aplikacije bez poslužitelja

Autor: Martin Luther
Video u nastavku pokazuje kako stvoriti jednostavnu Java aplikaciju koristeći Quarkus i implementirati je kao aplikaciju bez poslužitelja na Knative.

5. Quarkus: Zabavite se kodiranjem

Autor: Edson Yanaga
Video vodič za stvaranje vašeg prvog Quarkus projekta, koji vam omogućuje 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 povijest 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 programera: jednostavnost, ultra velike brzine, najbolje biblioteke i standardi.

8. Quarkus i subatomski raketni sustavi

Autor: Clement Escoffier
Kroz integraciju s GraalVM, Quarkus pruža ultrabrzo razvojno iskustvo i subatomsko okruženje za izvođenje. Autor govori o reaktivnoj strani Quarkusa i kako ga koristiti za izgradnju reaktivnih i streaming aplikacija.

9. Quarkus i brzi razvoj aplikacija u Eclipse MicroProfile

Autor: John Clingan
Kombinirajući Eclipse MicroProfile i Quarkus, programeri mogu kreirati kontejnerizirane MicroProfile aplikacije s punim značajkama koje se pokreću za desetke milisekundi. Video ide u detalje o tome kako kodirati kontejnersku MicroProfile aplikaciju za implementaciju na platformi Kubernetes.

10. Java, "Turbo" verzija

Autor: Marcus Biel
Autor pokazuje kako koristiti Quarkus za stvaranje super-malih, super-brzih Java spremnika koji omogućuju pravi napredak, posebno u okruženjima bez poslužitelja.



Izvor: www.habr.com

Dodajte komentar