Hur Quarkus kombinerar imperativ och reaktiv programmering

I år planerar vi att på allvar utveckla containerteman, Cloud-native Java и Kubernetes. En logisk fortsättning på dessa ämnen kommer redan att vara en berättelse om Quarkus-ramverket anses vara på Habré. Dagens artikel handlar mindre om designen av "subatomic superfast Java" och mer om löftet som Quarkus ger Enterprise.

Hur Quarkus kombinerar imperativ och reaktiv programmering

Java och JVM är fortfarande extremt populära, men när man arbetar med serverlösa teknologier och molnbaserade mikrotjänster används Java och andra JVM-språk mindre och mindre eftersom de tar upp för mycket minnesutrymme och är för långsamma att ladda, vilket gör dem dåligt lämpad för användning med kortlivade behållare. Som tur är börjar denna situation nu förändras tack vare Quarkus.

Supersnabba subatomära Java har nått en ny nivå!

42 releaser, 8 månaders samhällsarbete och 177 fantastiska utvecklare - resultatet av det hela var releasen i november 2019 Quarkus 1.0, en release som markerar en viktig milstolpe i utvecklingen av projektet och erbjuder många coola funktioner och möjligheter (du kan läsa mer om dem i meddelande).

Idag ska vi visa dig hur Quarkus kombinerar imperativa och reaktiva programmeringsmodeller till en enda reaktiv kärna. Vi börjar med en kort historik och går sedan in i detalj om vad Quarkus reaktiva kärndualism är och hur java-Utvecklare kan dra nytta av dessa fördelar.

Mikrotjänster, händelsedrivna arkitekturer и Server-funktioner – allt detta är, som man säger, på uppgång idag. Nyligen har skapandet av molncentrerade arkitekturer blivit mycket lättare och mer tillgängligt, men problem kvarstår – särskilt för Java-utvecklare. Till exempel, när det gäller serverlösa funktioner och mikrotjänster, finns det ett akut behov av att minska starttiden, minska minnesförbrukningen och ändå göra utvecklingen mer bekväm och njutbar. Java har gjort flera förbättringar de senaste åren, såsom förbättrad ergonomisk funktionalitet för containrar och så vidare. Men att få Java att fungera korrekt i en container är fortfarande en utmaning. Så vi börjar med att titta på några av Javas inneboende komplexitet, som är särskilt akuta när man utvecklar containerorienterade Java-applikationer.

Låt oss först titta på historien.

Hur Quarkus kombinerar imperativ och reaktiv programmering

Bäckar och containrar

Från och med version 8u131 började Java mer eller mindre stödja behållare på grund av förbättringar i ergonomisk funktionalitet. I synnerhet vet JVM nu hur många processorkärnor den körs på och kan konfigurera trådpooler – vanligtvis gaffel/join pooler – i enlighet med detta. Naturligtvis är detta bra, men låt oss säga att vi har en traditionell webbapplikation som använder HTTP-servlets och körs i Tomcat, Jetty, etc. Som ett resultat kommer den här applikationen att ge varje begäran en separat tråd och tillåta den att blockera denna tråd medan den väntar på I/O-operationer, till exempel vid åtkomst till databasen, filerna eller andra tjänster. Det vill säga storleken på en sådan applikation beror inte på antalet tillgängliga kärnor, utan på antalet samtidiga förfrågningar. Dessutom betyder det att kvoter eller begränsningar i Kubernetes på antalet kärnor inte kommer att vara till stor hjälp här, och saken kommer i slutändan att sluta i strypning.

Minnesutmattning

Trådar är minne. Och minnesbegränsningar inom behållaren är inte på något sätt ett universalmedel. Börja bara öka antalet applikationer och trådar, och förr eller senare kommer du att möta en kritisk ökning av växlingsfrekvensen och, som ett resultat, prestandaförsämring. Dessutom, om din applikation använder traditionella mikrotjänstramverk, eller ansluter till en databas, eller använder cachning, eller på annat sätt använder upp minne, behöver du uppenbarligen ett verktyg som låter dig titta in i JVM och se hur det hanterar minne utan att döda det. JVM själv (till exempel XX:+UseCGroupMemoryLimitForHeap). Och även om JVM sedan Java 9 har lärt sig att acceptera cgroups och anpassa sig därefter, förblir att reservera och hantera minne en ganska komplex fråga.

Kvoter och gränser

Java 11 introducerade stöd för CPU-kvoter (som PreferContainerQuotaForCPUCount). Kubernetes erbjuder även stöd för gränser och kvoter. Ja, allt detta är vettigt, men om applikationen återigen överskrider den tilldelade kvoten, slutar vi återigen med storleken - som är fallet med traditionella Java-applikationer - som bestäms av antalet kärnor och med tilldelningen av en separat tråd för varje begäran, då är det lite mening med allt detta.
Dessutom, om du använder kvoter och gränser eller utskalningsfunktionerna för plattformen som ligger bakom Kubernetes, löser sig inte problemet av sig självt. Vi spenderar helt enkelt mer resurser på att lösa det ursprungliga problemet eller slutar med överutgifter. Och om det är ett högbelastningssystem i ett offentligt offentligt moln, kommer vi nästan säkert att använda mer resurser än vi verkligen behöver.

Och vad ska man göra med allt detta?

För att uttrycka det enkelt, använd asynkrona och icke-blockerande I/O-bibliotek och ramverk som Netty, Vert.x eller Akka. De är mycket bättre lämpade att arbeta i containrar på grund av sin reaktiva natur. Tack vare icke-blockerande I/O kan samma tråd behandla flera samtidiga förfrågningar. Medan en begäran väntar på I/O-resultat släpps tråden som bearbetar den och tas över av en annan begäran. Och när I/O-resultaten äntligen kommer fram fortsätter behandlingen av den första begäran. Genom sammanflätad bearbetning av förfrågningar inom samma tråd kan du minska det totala antalet trådar och minska resursförbrukningen för att behandla förfrågningar.

Med icke-blockerande I/O blir antalet kärnor en nyckelparameter eftersom det bestämmer antalet I/O-trådar som kan exekveras parallellt. När det används på rätt sätt kan du effektivt fördela belastningen mellan kärnor och hantera högre arbetsbelastningar med färre resurser.

Hur, är det allt?

Nej, det är något annat. Reaktiv programmering hjälper till att utnyttja resurserna bättre, men har också ett pris. I synnerhet kommer koden att behöva skrivas om enligt principerna för icke-blockering och undvika att blockera I/O-trådar. Och det här är en helt annan modell för utveckling och utförande. Och även om det finns många användbara bibliotek här är det ändå en radikal förändring av det vanliga sättet att tänka.

Först måste du lära dig hur du skriver kod som körs asynkront. När du börjar använda icke-blockerande I/O måste du uttryckligen ange vad som ska hända när ett svar på en begäran tas emot. Att bara blockera och vänta fungerar inte längre. Istället kan du skicka återuppringningar, använda reaktiv programmering eller fortsättning. Men det är inte allt: för att använda icke-blockerande I/O behöver du både icke-blockerande servrar och klienter, helst överallt. När det gäller HTTP är allt enkelt, men det finns även databaser, filsystem och mycket mer.

Och även om total reaktivitet från slut till ände maximerar effektiviteten, kan en sådan förändring vara svår att klara av i praktiken. Därför blir förmågan att kombinera reaktiv och imperativ kod en förutsättning för att:

  1. Använd resurser effektivt i de mest belastade områdena i mjukvarusystemet;
  2. Använd enklare stilkod i de återstående delarna.

Vi presenterar Quarkus

Egentligen är detta kärnan i Quarkus - att kombinera reaktiva och imperativa modeller inom en enda körtidsmiljö.

Quarkus är baserat på Vert.x och Netty, med en rad reaktiva ramverk och tillägg ovanpå för att hjälpa utvecklaren. Quarkus är designad för att bygga inte bara HTTP-mikrotjänster utan även händelsedrivna arkitekturer. På grund av sin reaktiva natur fungerar den mycket effektivt med meddelandesystem (Apache Kafka, AMQP, etc.).

Tricket är hur man använder samma reaktiva motor för både imperativ och reaktiv kod.

Hur Quarkus kombinerar imperativ och reaktiv programmering

Quarkus gör detta briljant. Valet mellan imperativ och reaktiv är uppenbart - använd en reaktiv kärna för båda. Vad det verkligen hjälper med är snabb, icke-blockerande kod som hanterar nästan allt som passerar genom event-loop-tråden, aka IO-tråden. Men om du har klassiska REST- eller klientapplikationer har Quarkus en imperativ programmeringsmodell redo. Till exempel är HTTP-stöd i Quarkus baserat på användningen av en icke-blockerande och reaktiv motor (Eclipse Vert.x och Netty). Alla HTTP-förfrågningar som tas emot av din applikation skickas först genom en händelseslinga (IO-tråd) och skickas sedan till den del av koden som hanterar förfrågningarna. Beroende på destinationen kan förfrågningshanteringskoden anropas inom en separat tråd (den så kallade arbetstråden, som används i fallet med servlets och Jax-RS) eller använda käll-I/O-tråden (reaktiv väg).

Hur Quarkus kombinerar imperativ och reaktiv programmering

Anslutningar för meddelandesystem använder icke-blockerande klienter som körs ovanpå Vert.x-motorn. Därför kan du effektivt skicka, ta emot och bearbeta meddelanden från mellanprogram för meddelanden.

Webbplatsen Quarkus.io Här är några bra handledningar som hjälper dig att komma igång med Quarkus:

Vi har också skapat praktiska handledningar online för att lära dig olika aspekter av reaktiv programmering i bara en webbläsare, ingen IDE krävs och ingen dator krävs. Du kan hitta dessa lektioner här.

Användbara resurser

10 videolektioner om Quarkus för att bli bekant med ämnet

Som de säger på hemsidan Quarkus.io, quarkus - det är det Kubernetes-orienterad Java-stack, skräddarsydd för GraalVM och OpenJDK HotSpot och sammansatt från de bästa Java-biblioteken och -standarderna.

För att hjälpa dig förstå ämnet har vi valt ut 10 videohandledningar som täcker olika aspekter av Quarkus och exempel på dess användning:

1. Vi presenterar Quarkus: The Next Generation Java Framework för Kubernetes

Av Thomas Qvarnström och Jason Greene
Målet med Quarkus-projektet är att skapa en Java-plattform för Kubernetes och serverlösa miljöer, och att kombinera reaktiva och imperativa programmeringsmodeller till en enda runtime-miljö så att utvecklare flexibelt kan variera sitt tillvägagångssätt när de arbetar med ett brett utbud av distribuerade applikationsarkitekturer. Läs mer i introduktionsföreläsningen nedan.

2. Quarkus: Supersnabb Subatomic Java

Av: Burr Sutter
Den här videohandledningen från DevNation Live visar hur man använder Quarkus för att optimera Java-applikationer, API:er, mikrotjänster och serverlösa funktioner i en Kubernetes/OpenShift-miljö, vilket gör dem mycket mindre, snabbare och mer skalbara.

3. Quarkus och GraalVM: accelererar Hibernate till superhastigheter och krymper den till subatomära storlekar

Författare: Sanne Grinovero
Från presentationen kommer du att lära dig hur Quarkus kom till, hur det fungerar och hur det låter dig göra komplexa bibliotek, som Hibernate ORM, kompatibla med inbyggda GraalVM-bilder.

4. Lär dig att utveckla serverlösa applikationer

Författare: Martin Luther
Videon nedan visar hur man skapar en enkel Java-applikation med Quarkus och distribuerar den som en serverlös applikation på Knative.

5. Quarkus: Ha kul med kodning

Författare: Edson Yanaga
En videoguide för att skapa ditt första Quarkus-projekt, som låter dig förstå varför Quarkus vinner utvecklarnas hjärtan.

6. Java och containrar - vad deras framtid tillsammans kommer att bli

Postat av Mark Little
Den här presentationen introducerar Javas historia och förklarar varför Quarkus är Javas framtid.

7. Quarkus: Supersnabb Subatomic Java

Författare: Dimitris Andreadis
En översikt över fördelarna med Quarkus som har fått erkännande från utvecklare: enkelhet, ultrahöga hastigheter, de bästa biblioteken och standarderna.

8. Quarkus och subatomära raketsystem

Författare: Clement Escoffier
Genom integration med GraalVM ger Quarkus en ultrasnabb utvecklingsupplevelse och en subatomär runtime-miljö. Författaren berättar om den reaktiva sidan av Quarkus och hur man använder den för att bygga reaktiva och strömmande applikationer.

9. Quarkus och snabb applikationsutveckling i Eclipse MicroProfile

Författare: John Clingan
Genom att kombinera Eclipse MicroProfile och Quarkus, kan utvecklare skapa fullfjädrade containeriserade MicroProfile-applikationer som startar på tiotals millisekunder. Videon går i detalj om hur man kodar en containeriserad MicroProfile-applikation för distribution på Kubernetes-plattformen.

10. Java, "Turbo"-version

Författare: Marcus Biel
Författaren visar hur man använder Quarkus för att skapa supersmå, supersnabba Java-behållare som möjliggör verkliga genombrott, särskilt i serverlösa miljöer.



Källa: will.com

Lägg en kommentar