Hvordan Quarkus kombinerer imperativ og reaktiv programmering

I år planlegger vi seriøst å utvikle containertemaer, Cloud-native Java и Kubernetes. En logisk fortsettelse av disse temaene vil allerede være en historie om Quarkus-rammeverket ansett på Habré. Dagens artikkel handler mindre om utformingen av «subatomic superfast Java» og mer om løftet som Quarkus gir Enterprise.

Hvordan Quarkus kombinerer imperativ og reaktiv programmering

Java og JVM er fortsatt ekstremt populære, men når du jobber med serverløse teknologier og skybaserte mikrotjenester, brukes Java og andre JVM-språk mindre og mindre fordi de tar opp for mye minneplass og er for trege å laste, noe som gjør dem dårlig egnet for bruk med kortlivede beholdere. Heldigvis begynner denne situasjonen nå å endre seg takket være Quarkus.

Superrask subatomisk Java har nådd et nytt nivå!

42 utgivelser, 8 måneder med samfunnsarbeid og 177 fantastiske utviklere - resultatet av det hele var utgivelsen i november 2019 Quarkus 1.0, en utgivelse som markerer en viktig milepæl i utviklingen av prosjektet og tilbyr mange kule funksjoner og muligheter (du kan lese mer om dem i kunngjøringer).

I dag skal vi vise deg hvordan Quarkus kombinerer imperative og reaktive programmeringsmodeller til en enkelt reaktiv kjerne. Vi starter med en kort historie og går deretter i detalj om hva Quarkus' reaktive kjernedualisme er og hvordan Java-Utviklere kan dra nytte av disse fordelene.

Mikrotjenester, hendelsesdrevne arkitekturer и server-funksjoner – alt dette er, som de sier, på vei oppover i dag. Nylig har etableringen av skysentriske arkitekturer blitt mye enklere og mer tilgjengelig, men problemer gjenstår - spesielt for Java-utviklere. For eksempel, når det gjelder serverløse funksjoner og mikrotjenester, er det et presserende behov for å redusere oppstartstiden, redusere minneforbruket og fortsatt gjøre utviklingen mer praktisk og morsom. Java har gjort flere forbedringer de siste årene, for eksempel forbedret ergonomi-funksjonalitet for containere og så videre. Det er imidlertid fortsatt utfordrende å få Java til å fungere ordentlig i en container. Så vi starter med å se på noen av de iboende kompleksitetene til Java, som er spesielt akutte når man utvikler containerorienterte Java-applikasjoner.

La oss først se på historien.

Hvordan Quarkus kombinerer imperativ og reaktiv programmering

Bekker og beholdere

Fra og med versjon 8u131 begynte Java å mer eller mindre støtte containere på grunn av forbedringer i ergonomisk funksjonalitet. Spesielt vet JVM nå hvor mange prosessorkjerner den kjører på og kan konfigurere trådpooler – typisk gaffel/join-pooler – i henhold til dette. Selvfølgelig er dette flott, men la oss si at vi har en tradisjonell nettapplikasjon som bruker HTTP-servlets og kjører i Tomcat, Jetty, etc. Som et resultat vil denne applikasjonen gi hver forespørsel en egen tråd og tillate den å blokkere denne tråden mens den venter på I/O-operasjoner, for eksempel når du får tilgang til databasen, filer eller andre tjenester. Det vil si at størrelsen på en slik applikasjon ikke avhenger av antall tilgjengelige kjerner, men av antall samtidige forespørsler. I tillegg betyr dette at kvoter eller begrensninger i Kubernetes på antall kjerner ikke vil være til stor hjelp her, og saken vil til slutt ende med struping.

Utmattelse av hukommelsen

Tråder er minne. Og minnebegrensninger i beholderen er på ingen måte et universalmiddel. Bare begynn å øke antall applikasjoner og tråder, og før eller siden vil du møte en kritisk økning i byttefrekvens og, som et resultat, ytelsesforringelse. Dessuten, hvis applikasjonen din bruker tradisjonelle mikrotjenester-rammeverk, eller kobler til en database, eller bruker caching, eller på annen måte bruker opp minne, trenger du åpenbart et verktøy som lar deg se inne i JVM og se hvordan det administrerer minnet uten å drepe det. JVM selv (for eksempel XX:+UseCGroupMemoryLimitForHeap). Og selv om JVM siden Java 9 har lært å akseptere cgroups og tilpasse seg deretter, er det fortsatt en ganske kompleks sak å reservere og administrere minne.

Kvoter og grenser

Java 11 introduserte støtte for CPU-kvoter (som PreferContainerQuotaForCPUCount). Kubernetes tilbyr også støtte for grenser og kvoter. Ja, alt dette gir mening, men hvis applikasjonen igjen overskrider den tildelte kvoten, ender vi igjen opp med størrelsen - som tilfellet er med tradisjonelle Java-applikasjoner - bestemt av antall kjerner og med tildeling av en egen tråd for hver forespørsel, da er det liten mening i alt dette.
I tillegg, hvis du bruker kvoter og grenser eller utskaleringsfunksjonene til plattformen som ligger til grunn for Kubernetes, løser heller ikke problemet seg selv. Vi bruker ganske enkelt mer ressurser på å løse det opprinnelige problemet eller ender opp med overforbruk. Og hvis det er et høybelastningssystem i en offentlig offentlig sky, ender vi nesten helt sikkert opp med å bruke flere ressurser enn vi egentlig trenger.

Og hva skal man gjøre med alt dette?

For å si det enkelt, bruk asynkrone og ikke-blokkerende I/O-biblioteker og rammeverk som Netty, Vert.x eller Akka. De er mye bedre egnet til å jobbe i containere på grunn av deres reaktive natur. Takket være ikke-blokkerende I/O kan den samme tråden behandle flere samtidige forespørsler. Mens en forespørsel venter på I/O-resultater, frigis tråden som behandler den og overtas av en annen forespørsel. Og når I/O-resultatene endelig kommer, fortsetter behandlingen av den første forespørselen. Ved sammenflettet behandling av forespørsler innenfor samme tråd kan du redusere det totale antallet tråder og redusere ressursforbruket for behandling av forespørsler.

Med ikke-blokkerende I/O blir antall kjerner en nøkkelparameter fordi det bestemmer antall I/O-tråder som kan kjøres parallelt. Når det brukes riktig, lar dette deg effektivt fordele belastningen mellom kjerner og håndtere høyere arbeidsbelastninger med færre ressurser.

Hvordan, er det alt?

Nei, det er noe annet. Reaktiv programmering bidrar til å utnytte ressursene bedre, men har også en pris. Spesielt vil koden måtte skrives om i henhold til prinsippene for ikke-blokkering og unngå blokkering av I/O-tråder. Og dette er en helt annen modell for utvikling og utførelse. Og selv om det er mange nyttige biblioteker her, er det likevel en radikal endring i den vanlige tankegangen.

Først må du lære hvordan du skriver kode som kjører asynkront. Når du begynner å bruke ikke-blokkerende I/O, må du spesifisere eksplisitt hva som skal skje når et svar på en forespørsel mottas. Bare blokkering og venting fungerer ikke lenger. I stedet kan du sende tilbakeringinger, bruke reaktiv programmering eller fortsettelse. Men det er ikke alt: for å bruke ikke-blokkerende I/O trenger du både ikke-blokkerende servere og klienter, helst overalt. Når det gjelder HTTP er alt enkelt, men det finnes også databaser, filsystemer og mye mer.

Og selv om total ende-til-ende-reaktivitet maksimerer effektiviteten, kan et slikt skifte være vanskelig å tåle i praksis. Derfor blir evnen til å kombinere reaktiv og imperativ kode en forutsetning for å:

  1. Bruk ressurser effektivt i de mest belastede områdene av programvaresystemet;
  2. Bruk enklere stilkode i de resterende delene.

Vi introduserer Quarkus

Faktisk er dette essensen av Quarkus - å kombinere reaktive og imperative modeller i ett enkelt kjøretidsmiljø.

Quarkus er basert på Vert.x og Netty, med en rekke reaktive rammeverk og utvidelser på toppen for å hjelpe utvikleren. Quarkus er designet for å bygge ikke bare HTTP-mikrotjenester, men også hendelsesdrevne arkitekturer. På grunn av sin reaktive natur fungerer den veldig effektivt med meldingssystemer (Apache Kafka, AMQP, etc.).

Trikset er hvordan du bruker den samme reaktive motoren for både imperativ og reaktiv kode.

Hvordan Quarkus kombinerer imperativ og reaktiv programmering

Quarkus gjør dette strålende. Valget mellom imperativ og reaktiv er åpenbart - bruk en reaktiv kjerne for begge. Det det virkelig hjelper med er rask, ikke-blokkerende kode som håndterer nesten alt som går gjennom event-loop-tråden, også kjent som IO-tråden. Men hvis du har klassiske REST- eller klientsideapplikasjoner, har Quarkus en imperativ programmeringsmodell klar. For eksempel er HTTP-støtte i Quarkus basert på bruk av en ikke-blokkerende og reaktiv motor (Eclipse Vert.x og Netty). Alle HTTP-forespørsler som mottas av applikasjonen din, sendes først gjennom en hendelsesløkke (IO Thread) og sendes deretter til den delen av koden som administrerer forespørslene. Avhengig av destinasjonen, kan forespørselshåndteringskoden kalles i en egen tråd (den såkalte arbeidertråden, brukt i tilfellet med servlets og Jax-RS) eller bruke kilde-I/O-tråden (reaktiv rute).

Hvordan Quarkus kombinerer imperativ og reaktiv programmering

Meldingssystemkoblinger bruker ikke-blokkerende klienter som kjører på toppen av Vert.x-motoren. Derfor kan du effektivt sende, motta og behandle meldinger fra mellomvaresystemer for meldinger.

Området Quarkus.io Her er noen gode veiledninger for å hjelpe deg med å komme i gang med Quarkus:

Vi har også laget praktiske opplæringsprogrammer på nettet for å lære deg ulike aspekter av reaktiv programmering i bare en nettleser, ingen IDE nødvendig, og ingen datamaskin nødvendig. Du kan finne disse leksjonene her.

Nyttige ressurser

10 videotimer på Quarkus for å bli kjent med temaet

Som de sier på nettsiden Quarkus.io, quarkus - Er Kubernetes-orientert Java-stack, skreddersydd for GraalVM og OpenJDK HotSpot og satt sammen fra de beste Java-bibliotekene og -standardene.

For å hjelpe deg med å forstå emnet har vi valgt ut 10 videoopplæringer som dekker ulike aspekter av Quarkus og eksempler på bruken:

1. Vi introduserer Quarkus: The Next Generation Java Framework for Kubernetes

Av Thomas Qvarnstrom og Jason Greene
Målet med Quarkus-prosjektet er å lage en Java-plattform for Kubernetes og serverløse miljøer, og å kombinere reaktive og imperative programmeringsmodeller i ett enkelt kjøretidsmiljø slik at utviklere fleksibelt kan variere sin tilnærming når de jobber med et bredt spekter av distribuerte applikasjonsarkitekturer. Finn ut mer i introduksjonsforelesningen nedenfor.

2. Quarkus: Superrask Subatomic Java

Av: Burr Sutter
Denne videoopplæringen fra DevNation Live demonstrerer hvordan du bruker Quarkus til å optimalisere Java-applikasjoner, API-er, mikrotjenester og serverløse funksjoner i et Kubernetes/OpenShift-miljø, noe som gjør dem mye mindre, raskere og mer skalerbare.

3. Quarkus og GraalVM: akselererer Hibernate til superhastigheter og krymper den til subatomære størrelser

Forfatter: Sanne Grinovero
Fra presentasjonen vil du lære hvordan Quarkus ble til, hvordan det fungerer, og hvordan det lar deg gjøre komplekse biblioteker, som Hibernate ORM, kompatible med native GraalVM-bilder.

4. Lær å utvikle serverløse applikasjoner

Forfatter: Martin Luther
Videoen nedenfor viser hvordan du lager en enkel Java-applikasjon ved hjelp av Quarkus og distribuerer den som en serverløs applikasjon på Knative.

5. Quarkus: Ha det gøy med koding

Forfatter: Edson Yanaga
En videoguide for å lage ditt første Quarkus-prosjekt, som lar deg forstå hvorfor Quarkus vinner utviklernes hjerter.

6. Java og containere - hva deres fremtid sammen blir

Skrevet av Mark Little
Denne presentasjonen introduserer historien til Java og forklarer hvorfor Quarkus er fremtiden til Java.

7. Quarkus: Superrask Subatomic Java

Forfatter: Dimitris Andreadis
En oversikt over fordelene med Quarkus som har fått anerkjennelse fra utviklere: enkelhet, ultrahøye hastigheter, de beste bibliotekene og standardene.

8. Quarkus og subatomære rakettsystemer

Forfatter: Clement Escoffier
Gjennom integrasjon med GraalVM gir Quarkus en ultrarask utviklingsopplevelse og et subatomisk kjøretidsmiljø. Forfatteren snakker om den reaktive siden av Quarkus og hvordan du bruker den til å bygge reaktive og strømmeapplikasjoner.

9. Quarkus og rask applikasjonsutvikling i Eclipse MicroProfile

Forfatter: John Clingan
Ved å kombinere Eclipse MicroProfile og Quarkus kan utviklere lage fullfunksjons containeriserte MicroProfile-applikasjoner som starter på titalls millisekunder. Videoen går i detalj om hvordan du koder en containerisert MicroProfile-applikasjon for distribusjon på Kubernetes-plattformen.

10. Java, «Turbo»-versjon

Forfatter: Marcus Biel
Forfatteren viser hvordan du bruker Quarkus til å lage supersmå, superraske Java-beholdere som muliggjør virkelige gjennombrudd, spesielt i serverløse miljøer.



Kilde: www.habr.com

Legg til en kommentar