Native sammanställning i Quarkus - varför det är viktigt

Hej alla! Det här är det andra inlägget i vår serie om Quarkus - idag ska vi prata om inbyggd sammanställning.

Native sammanställning i Quarkus - varför det är viktigt

quarkus är en Java-stack skräddarsydd för Kubernetes. Även om det säkert finns mycket mer att göra här, har vi gjort mycket bra arbete på många aspekter, inklusive att optimera JVM och ett antal ramverk. En av egenskaperna hos Quarkus som har väckt ökat intresse från utvecklare är dess omfattande, sömlösa tillvägagångssätt för att omvandla Java-kod till körbara filer för ett specifikt operativsystem (så kallad "native compilation"), liknande C och C++, där sådan kompilering inträffar vanligtvis i slutet av en cykel av bygg, test och distribution.

Och även om inbyggd kompilering är viktig, som vi kommer att visa nedan, bör det noteras att Quarkus fungerar riktigt bra på den vanligaste Java-maskinen, OpenJDK Hotspot, tack vare de prestandaförbättringar som vi har implementerat i hela stacken. Därför bör inbyggd kompilering betraktas som en extra bonus som kan användas efter önskemål eller behov. Faktum är att Quarkus förlitar sig mycket på OpenJDK när det kommer till inbyggda bilder. Och dev-läget, som är varmt accepterat av utvecklare, säkerställer nästan omedelbar testning av ändringar på grund av de avancerade funktionerna för dynamisk kodexekvering implementerad i Hotspot. Dessutom, när du skapar inbyggda GraalVM-bilder, används OpenJDK-klassbiblioteket och HotSpot-funktioner.

Så varför behöver du inbyggd kompilering om allt redan är perfekt optimerat? Vi kommer att försöka svara på denna fråga nedan.

Låt oss börja med det uppenbara: Red Hat har lång erfarenhet av att optimera JVM, stackar och ramverk under projektutveckling JBoss, Inklusive:

  • Den första applikationsservern som fungerar i molnet på plattformen Red Hat OpenShift.
  • Den första applikationsservern för att köras på datorer Koppla in PC.
  • Den första applikationsservern att köra på hallon Pi.
  • En rad projekt som körs på enheter Android.

Vi har hanterat utmaningarna med att köra Java-applikationer i molnet och på resursbegränsade enheter (läs: IoT) i många år och har lärt oss att få ut det mesta av JVM när det gäller prestanda och minnesoptimering. Som många andra har vi arbetat med inbyggd kompilering av Java-applikationer under lång tid G.C.J., avian, Excelsior JET och även Dalvik och vi är väl medvetna om för- och nackdelarna med detta tillvägagångssätt (till exempel dilemmat att välja mellan universaliteten "bygg en gång – kör var som helst" och det faktum att kompilerade applikationer är mindre och körs snabbare).

Varför är det viktigt att överväga dessa för- och nackdelar? För i vissa situationer blir deras förhållande avgörande:

  • Till exempel i serverlösa/händelsedrivna miljöer där tjänster måste helt enkelt börja i (hård eller mjuk) realtid för att hinna svara på händelser. Till skillnad från långlivade beständiga tjänster, här ökar varaktigheten av en kallstart svarstiden på en förfrågan kritiskt. JVM tar fortfarande en betydande tid att starta upp, och även om detta i vissa fall kan reduceras med rena hårdvarumetoder, kan skillnaden mellan en sekund och 5 millisekunder vara skillnaden mellan liv och död. Ja, här kan du leka med att skapa en het reserv av Java-maskiner (vilket vi till exempel gjorde med porta OpenWhisk till Knative), men detta i sig garanterar inte att det kommer att finnas tillräckligt många JVM:er för att behandla förfrågningar när belastningen skalas. Och ur ekonomisk synvinkel är detta förmodligen inte det mest korrekta alternativet.
  • Vidare finns det en annan aspekt som ofta dyker upp: multitenancy. Trots att JVM:er har kommit väldigt nära operativsystem i sina möjligheter, är de fortfarande inte kapabla att göra det vi är så vana vid i Linux – att isolera processer. Därför kan ett fel i en tråd få ner hela Java-maskinen. Många människor försöker komma runt denna nackdel genom att dedikera en separat JVM för varje användares applikationer för att minimera konsekvenserna av ett misslyckande. Detta är ganska logiskt, men passar inte bra med skalning.
  • Dessutom, för molnorienterade applikationer, är en viktig indikator tätheten av tjänster på värden. Övergång till metodik 12 applikationsfaktorer, mikrotjänster och Kubernetes ökar antalet Java-maskiner per applikation. Det vill säga, å ena sidan ger allt detta elasticitet och tillförlitlighet, men samtidigt ökar också förbrukningen av basminne vad gäller service, och en del av dessa utgifter är inte alltid strikt nödvändiga. Statiskt kompilerade körbara filer gynnas här på grund av olika optimeringstekniker, såsom eliminering av död kod på låg nivå, när den slutliga bilden endast inkluderar de delar av ramverken (inklusive själva JDK) som tjänsten faktiskt använder. Därför hjälper Quarkus inbyggd kompilering till att placera tjänsteinstanser tätt på värden utan att kompromissa med säkerheten.

Egentligen räcker ovanstående argument redan för att förstå motiveringen av inhemsk sammanställning från Quarkus-projektdeltagarnas synvinkel. Det finns dock en annan, icke-teknisk, men också viktig anledning: under de senaste åren har många programmerare och utvecklingsföretag övergett Java till förmån för nya programmeringsspråk, i tron ​​att Java, tillsammans med sina JVM, stackar och ramverk, har blivit alltför minneshungrig, för långsam osv.

Men vanan att använda samma verktyg för att lösa alla problem är det är inte alltid rätt. Ibland är det bättre att ta ett steg tillbaka och leta efter något annat. Och om Quarkus får folk att pausa och tänka, då är det bra för hela Java-ekosystemet. Quarkus representerar en innovativ syn på hur man bygger effektivare applikationer, vilket gör Java mer relevant för nya applikationsarkitekturer som serverlös. På grund av dess utbyggbarhet kommer Quarkus förhoppningsvis att ha ett helt ekosystem av Java-tillägg, vilket avsevärt ökar antalet ramverk som kommer att stödja inbyggd kompilering i applikationer direkt.

Källa: will.com

Lägg en kommentar