Uw Java-toepassingen in een container plaatsen

Dit artikel bevat een overzicht van aanbevolen strategieën en instellingen voor het containeriseren van Java-toepassingen.

Wanneer u een Java-toepassing in een container plaatst, moet u zorgvuldig overwegen hoeveel CPU-tijd de container beschikbaar heeft. Bedenk vervolgens hoeveel geheugen er beschikbaar is in termen van de totale hoeveelheid geheugen en de heapgrootte van de Java Virtual Machine (JVM). In containeromgevingen hebben toepassingen mogelijk toegang tot alle processors en kunnen daarom meerdere threads parallel worden uitgevoerd. Het is echter gebruikelijk dat containers een CPU-quotum hebben toegepast dat de toegang tot CPU's kan beperken.

De JVM heeft heuristieken om het aantal 'beschikbare processors' te bepalen op basis van cpu-quotum, wat de prestaties van Java-toepassingen aanzienlijk kan beïnvloeden. Het geheugen dat is toegewezen aan de container zelf en de grootte van het heap-gebied voor de JVM zijn net zo belangrijk als de processors. Deze factoren bepalen het gedrag van de garbagecollection (GC) en de algehele prestaties van het systeem.

Een nieuwe toepassing containeriseren

Wanneer u een Java-workload voor een nieuwe toepassing in een container opneemt, moet u rekening houden met twee dingen bij het nadenken over geheugen:

  • Het geheugen dat is toegewezen aan de container zelf.
  • De hoeveelheid geheugen die beschikbaar is voor het Java-proces.

Inzicht in de standaard ergonomische JVM

Toepassingen hebben een beginpunt en instellingen nodig. De JVM heeft standaard ergonomische waarden met vooraf gedefinieerde waarden die zijn gebaseerd op het aantal beschikbare processors en de hoeveelheid geheugen in het systeem. De standaardwaarden die in de volgende tabellen worden weergegeven, worden gebruikt wanneer de JVM wordt gestart zonder specifieke opstartvlagken of parameters.

In de volgende tabel ziet u de standaard GC die wordt gebruikt voor de beschikbare resources:

Beschikbare resources Standaard GC
Een willekeurig aantal processors
Maximaal 1791 MB geheugen
SerialGC
2+ processors
1792 MB of meer geheugen
G1GC

In de volgende tabel ziet u de standaard maximale heapgrootte, afhankelijk van de hoeveelheid geheugen die beschikbaar is in de omgeving waarin de JVM wordt uitgevoerd:

Beschikbaar geheugen Standaard maximale heapgrootte
Tot 256 MB 50% van het beschikbare geheugen
256 MB tot 512 MB ~127 MB
Meer dan 512 MB 25% van het beschikbare geheugen

De standaard initiële heapgrootte is 1/64 van het beschikbare geheugen.

Deze waarden zijn geldig voor OpenJDK 11 en hoger, en voor de meeste distributies, waaronder Microsoft Build van OpenJDK, Azul Zulu, Eclipse Temurin, Oracle OpenJDK en andere.

Containergeheugen bepalen

Kies een containergeheugenhoeveelheid die het beste past bij uw werkbelasting, afhankelijk van de behoeften van uw toepassing en de bijbehorende onderscheidende gebruikspatronen. Als uw toepassing bijvoorbeeld grote objectgrafieken maakt, hebt u waarschijnlijk meer geheugen nodig dan u nodig hebt voor toepassingen met veel kleine objectgrafieken.

Tip

Als u niet weet hoeveel geheugen u moet toewijzen, is een goed startpunt 4 GB.

JVM-heap-geheugen bepalen

Wanneer u JVM-heap-geheugen toewijst, moet u er rekening mee houden dat de JVM meer geheugen nodig heeft dan alleen wat wordt gebruikt voor de JVM-heap. Wanneer u het maximale JVM-heap-geheugen instelt, mag deze nooit gelijk zijn aan de hoeveelheid containergeheugen, omdat dit tot OOM-fouten (Out of Memory) van de container leidt en container crasht.

Tip

Wijs 75% van het containergeheugen toe voor de JVM-heap.

Op OpenJDK 11 en hoger kunt u de grootte van de JVM-heap op de volgende manieren instellen:

Beschrijving Vlag Voorbeelden
Vaste waarde -Xmx -Xmx4g
Dynamische waarde -XX:MaxRAMPercentage -XX:MaxRAMPercentage=75

Minimale/initiële heapgrootte

Wanneer de omgeving gegarandeerd een bepaalde hoeveelheid geheugen heeft gereserveerd voor een JVM-instantie, zoals in een container, moet u de minimale heap-grootte (of initiële heapgrootte) instellen op dezelfde grootte als de maximale heapgrootte. Deze instelling geeft aan dat de JVM niet de taak moet uitvoeren om geheugen vrij te maken voor het besturingssysteem.

Als u een minimale heap-grootte wilt instellen, gebruikt -Xms u deze voor absolute bedragen of -XX:InitialRAMPercentage voor percentagebedragen.

Belangrijk

De vlag -XX:MinRAMPercentage, ondanks wat de naam suggereert, wordt gebruikt voor het instellen van het standaard maximum RAM-percentage voor systemen met maximaal 256 MB RAM beschikbaar in het systeem.

Chart showing the default heap size on OpenJDK 17.

Bepalen welke GC moet worden gebruikt

Eerder hebt u bepaald hoeveel JVM heap-geheugen u moet beginnen. De volgende stap is het kiezen van uw GC. De hoeveelheid maximaal JVM-heapgeheugen dat u hebt, is vaak een factor bij het kiezen van uw GC. In de volgende tabel worden de kenmerken van elke GC beschreven.

Factoren SerialGC ParallelGC G1GC ZGC ShenandoahGC
Aantal kerngeheugens 1 2 2 2 2
Meerdere threads Nr. Ja Ja Ja Ja
Grootte van Java-heap <4 GBytes <4 GBytes >4 GBytes >4 GBytes >4 GBytes
Onderbreken Ja Ja Ja Ja (<1 ms) Ja (<10 ms)
Overhead Minimaal Minimaal Gemiddeld Gemiddeld Gemiddeld
Tail-latency Effect Hoog Hoog Hoog Laag Gemiddeld
JDK-versie Alle Alle JDK 8+ JDK 17+ JDK 11+
Ideaal voor Enkele kern kleine heaps Multi-core kleine heaps of batchworkloads met elke heap-grootte Responsief in middelgrote tot grote heaps (request-response/DB-interacties) Responsief in middelgrote tot grote heaps (request-response/DB-interacties) Responsief in middelgrote tot grote heaps (request-response/DB-interacties)

Tip

Voor de meeste microservicetoepassingen voor algemeen gebruik begint u met de parallelle GC.

Bepalen hoeveel CPU-kernen er nodig zijn

Voor andere GC's dan SerialGC raden we twee of meer vCPU-kernen aan, of ten minste 2000mcpu_limit op Kubernetes. We raden u niet aan om iets minder dan 1 vCPU-kern te selecteren in containeromgevingen.

Tip

Als u niet weet hoeveel kernen u moet beginnen, is een goede keuze 2 vCPU-kernen.

Kies een beginpunt

We raden u aan om te beginnen met twee replica's of exemplaren in containerindelingsomgevingen zoals Kubernetes, OpenShift, Azure Spring Apps, Azure Container Apps en Azure-app Service. De volgende tabel bevat een overzicht van de aanbevolen uitgangspunten voor de containerisatie van uw nieuwe Java-toepassing.

vCPU-kernen Containergeheugen Grootte van JVM-heap GC Replica's
2 4 GB 75% ParallelGC 2

De te gebruiken JVM-parameters zijn: -XX:+UseParallelGC -XX:MaxRAMPercentage=75

Een bestaande (on-premises) toepassing in een container plaatsen

Als uw toepassing al on-premises of op een VIRTUELE machine in de cloud wordt uitgevoerd, raden we u aan om te beginnen met:

  • Dezelfde hoeveelheid geheugen waartoe de toepassing momenteel toegang heeft.
  • Hetzelfde aantal CPU's (vCPU-kernen) dat de toepassing momenteel beschikbaar heeft.
  • Dezelfde JVM-parameters die u momenteel gebruikt.

Als de combinatie van vCPU-kernen en/of containergeheugen niet beschikbaar is, kiest u het dichtstbijzijnde kerngeheugen en rondt u de vCPU-kernen en het containergeheugen af.

Volgende stappen

Nu u de algemene aanbevelingen voor het containeriseren van Java-toepassingen begrijpt, gaat u verder met het volgende artikel om een containerisatiebasislijn op te stellen: