Anmerkung
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Dieser Artikel enthält eine Übersicht über empfohlene Strategien und Einstellungen für die Containerisierung von Java-Anwendungen. Berücksichtigen Sie beim Containerisieren einer Java-Anwendung sorgfältig, wie viel CPU-Zeit der Container verfügbar ist. Überlegen Sie dann, wie viel Arbeitsspeicher sowohl im Hinblick auf die Gesamtspeichermenge als auch die Heap-Größe des virtuellen Java-Computers (JVM) verfügbar ist. In containerisierten Umgebungen haben Anwendungen möglicherweise Zugriff auf alle Prozessoren und können daher mehrere Threads parallel ausführen. Es ist jedoch üblich, dass Container über ein CPU-Kontingent verfügen, das den Zugriff auf CPUs möglicherweise drosselt.
Die JVM verfügt über Heuristiken, um die Anzahl der "verfügbaren Prozessoren" basierend auf dem CPU-Kontingent zu bestimmen, was die Leistung von Java-Anwendungen erheblich beeinflussen kann. Der dem Container zugewiesene Speicher und die Größe des Heapbereichs für das JVM sind ebenso wichtig wie die Prozessoren. Diese Faktoren bestimmen das Verhalten des Garbage Collector (GC) und die Gesamtleistung des Systems.
Containerisieren einer neuen Anwendung
Wenn Sie eine Java-Arbeitslast für eine neue Anwendung containerisieren, müssen Sie zwei Dinge berücksichtigen, wenn Sie den Arbeitsspeicher betrachten:
- Der dem Container zugeordnete Speicher selbst.
- Die Für den Java-Prozess verfügbare Arbeitsspeichermenge.
Grundlegendes zu JVM-Standard-Ergonomie
Anwendungen benötigen einen Ausgangspunkt und Einstellungen. Das JVM verfügt über Standard-Ergonomie mit vordefinierten Werten, die auf der Anzahl der verfügbaren Prozessoren und der Menge des Arbeitsspeichers im System basieren. Die in den folgenden Tabellen gezeigten Standardwerte werden verwendet, wenn das JVM ohne bestimmte Startflags oder Parameter gestartet wird.
Die folgende Tabelle zeigt die Standard-GC, die für die verfügbaren Ressourcen verwendet wird:
| Verfügbare Ressourcen | Standard-GC |
|---|---|
| Beliebige Anzahl von Prozessoren Bis zu 1.791 MB Arbeitsspeicher |
SerialGC |
| 2+ Prozessoren 1.792 MB oder mehr Arbeitsspeicher |
G1GC |
Die folgende Tabelle zeigt die standardmäßige maximale Heap-Größe, je nachdem, wie viel Arbeitsspeicher in der Umgebung verfügbar ist, in der der JVM ausgeführt wird:
| Verfügbarer Arbeitsspeicher | Standardmäßige maximale Heapgröße |
|---|---|
| Bis zu 256 MB | 50 % des verfügbaren Speichers |
| 256 MB bis 512 MB | ~127 MB |
| Mehr als 512 MB | 25 % des verfügbaren Speichers |
Die standardmäßige anfängliche Heapgröße beträgt 1/64 des verfügbaren Arbeitsspeichers. Diese Werte gelten für OpenJDK 11 und höher und für die meisten Verteilungen, einschließlich Microsoft Build of OpenJDK, Azul Zulu, Eclipse Temurin, Oracle OpenJDK und anderen.
Speicher des Containers bestimmen
Wählen Sie einen Containerspeicherbetrag aus, der Ihrer Arbeitslast am besten entspricht, abhängig von den Anforderungen Ihrer Anwendung und ihren unverwechselbaren Verwendungsmustern. Wenn Ihre Anwendung beispielsweise große Objektdiagramme erstellt, benötigen Sie wahrscheinlich mehr Arbeitsspeicher als für Anwendungen mit vielen kleinen Objektdiagrammen.
Tipp
Wenn Sie nicht wissen, wie viel Arbeitsspeicher zugewiesen werden soll, ist ein guter Ausgangspunkt 4 GB.
JVM Heap-Speicher bestimmen
Wenn Sie JVM Heap-Speicher zuweisen, benötigt die JVM mehr Speicher als für den JVM Heap verwendet wird. Wenn Sie den maximalen JVM-Heapspeicher festlegen, sollte er niemals der Menge des Containerspeichers entsprechen, da dadurch Fehler im Container außerhalb des Arbeitsspeichers (Out of Memory, OOM) und Containerabstürzen verursacht werden.
Tipp
Weisen Sie 75% des Containerspeichers für den JVM Heap zu.
Auf OpenJDK 11 und höher können Sie die JVM-Heapgröße auf folgende Weise festlegen:
| BESCHREIBUNG | Flagge | Beispiele |
|---|---|---|
| Fester Wert | -Xmx |
-Xmx4g |
| Dynamischer Wert | -XX:MaxRAMPercentage |
-XX:MaxRAMPercentage=75 |
Minimale/anfängliche Heap-Größe
Wenn die Umgebung garantiert einen bestimmten Speicherplatz für eine JVM-Instanz reserviert hat, z. B. in einem Container, sollten Sie die minimale Heap-Größe ( oder die anfängliche Heap-Größe ) auf dieselbe Größe wie die maximale Heapgröße festlegen. Diese Einstellung gibt dem JVM an, dass er nicht die Aufgabe ausführen sollte, Arbeitsspeicher auf das Betriebssystem freizugeben.
Um eine Mindestgröße für den Heap festzulegen, verwenden Sie -Xms für absolute Werte oder -XX:InitialRAMPercentage für prozentuale Werte.
Von Bedeutung
Das Kennzeichen -XX:MinRAMPercentagewird trotz des Namens verwendet, um den standardmäßigen maximalen RAM-Prozentsatz für Systeme mit bis zu 256 MB RAM festzulegen, der im System verfügbar ist.
Bestimmen, welcher GC verwendet werden soll
Zuvor haben Sie die Menge an JVM Heap-Speicher festgelegt, mit der Sie beginnen möchten. Der nächste Schritt ist die Auswahl Ihres GC. Die Größe des maximalen JVM Heap-Speichers, über den Sie verfügen, ist oft ein Faktor bei der Wahl Ihres GC. In der folgenden Tabelle werden die Merkmale der einzelnen GC beschrieben.
| Faktoren | SerialGC | ParallelGC | G1GC | ZGC | ShenandoahGC |
|---|---|---|---|---|---|
| Anzahl von Kernen | 1 | 2 | 2 | 2 | 2 |
| Multithreading | Nein | Ja | Ja | Ja | Ja |
| Java Heap-Größe | <4 GByte | <4 GByte | >4 GByte | >4 GByte | >4 GByte |
| Anhalten | Ja | Ja | Ja | Ja (<1 ms) | Ja (<10 ms) |
| Mehraufwand | Wenig | Wenig | Mäßig | Mäßig | Mäßig |
| Tail-Latency-Effekt | Hoch | Hoch | Hoch | Niedrig | Mäßig |
| JDK-Version | Alle | Alle | JDK 8+ | JDK 17+ | JDK 11+ |
| Am besten geeignet für: | Kleine Heaps für einen Kern | Multi-Core kleine Heaps oder Batch Workloads mit beliebiger Heap-Größe | Responsive in mittleren bis großen Heaps (Anfrage-Antwort/DB-Interaktionen) | Responsive in mittleren bis großen Heaps (Anfrage-Antwort/DB-Interaktionen) | Responsive in mittleren bis großen Heaps (Anfrage-Antwort/DB-Interaktionen) |
Tipp
Für die meisten allgemeinen Microservice-Anwendungen beginnen Sie mit der Parallel GC.
Ermitteln, wie viele CPU-Kerne benötigt werden
Für jede andere GC als SerialGC empfehlen wir zwei oder mehr vCPU-Kerne - oder mindestens 2000m für cpu_limit auf Kubernetes. Es wird nicht empfohlen, etwas anderes als einen vCPU-Kern in containerisierten Umgebungen auszuwählen.
Tipp
Wenn Sie nicht wissen, mit wie vielen Kernen sie beginnen sollen, ist eine gute Wahl zwei vCPU-Kerne.
Auswählen eines Ausgangspunkts
Es wird empfohlen, mit zwei Replikaten oder Instanzen in Container-Orchestrierungsumgebungen wie Kubernetes, OpenShift, Azure Spring Apps, Azure Container Apps und Azure App Service zu beginnen. In der folgenden Tabelle sind die empfohlenen Ausgangspunkte für die Containerisierung Ihrer neuen Java-Anwendung zusammengefasst.
| vCPU-Kerne | Containerspeicher | JVM-Heapgröße | GC | Replikate |
|---|---|---|---|---|
| 2 | 4 GB | 75 % | ParallelGC | 2 |
Verwenden Sie die folgenden JVM-Parameter:
-XX:+UseParallelGC -XX:MaxRAMPercentage=75
Containerisieren einer vorhandenen lokalen Anwendung
Wenn Ihre Anwendung bereits lokal oder auf einer VM in der Cloud ausgeführt wird, sollten Sie mit der folgenden Konfiguration beginnen:
- Die gleiche Arbeitsspeichermenge, auf die die Anwendung derzeit Zugriff hat.
- Die gleiche Anzahl von CPUs oder vCPU-Kernen, die die Anwendung derzeit verfügbar hat.
- Dieselben JVM-Parameter, die Sie derzeit verwenden.
Wenn die vCPU-Kerne oder die Containerspeicherkombination nicht verfügbar ist, wählen Sie den nächstgelegenen Kern aus, um die vCPU-Kerne und den Containerspeicher aufzurunden.
Nächste Schritte
Nachdem Sie nun die allgemeinen Empfehlungen für die Containerisierung von Java-Anwendungen verstanden haben, fahren Sie mit dem folgenden Artikel fort, um einen Containerisierungsbasisplan einzurichten: