Kontainerisasi aplikasi Java Anda

Artikel ini memberikan gambaran umum tentang strategi dan pengaturan yang direkomendasikan untuk kontainerisasi aplikasi Java. Saat Anda mengkontainerisasi aplikasi Java, pertimbangkan dengan cermat berapa banyak waktu CPU yang tersedia kontainer. Kemudian pertimbangkan berapa banyak memori yang tersedia baik dalam hal jumlah total memori dan ukuran timbunan Java Virtual Machine (JVM). Di lingkungan kontainer, aplikasi mungkin memiliki akses ke semua prosesor dan oleh karena itu dapat menjalankan beberapa utas secara paralel. Sering kali, kontainer memiliki kuota CPU yang diterapkan yang bisa membatasi akses ke CPU.

JVM menggunakan heuristik untuk menentukan jumlah "prosesor yang tersedia" berdasarkan kuota CPU, yang dapat secara dramatis memengaruhi performa aplikasi Java. Memori yang dialokasikan untuk kontainer itu sendiri dan ukuran area timbunan untuk JVM sama pentingnya dengan prosesor. Faktor-faktor ini menentukan perilaku pengumpul sampah (GC) dan performa sistem secara keseluruhan.

Petunjuk / Saran

Jika Anda tidak ingin menyetel pengaturan ini secara manual, Azure Command Launcher untuk Java (jaz) secara otomatis menerapkan default JVM cloud-native untuk Anda. Ini adalah pengganti langsung untuk perintah java yang mendeteksi batas kontainer dan memilih ukuran heap serta flag GC yang paling sesuai. Untuk informasi selengkapnya, lihat Menyetel JVM secara otomatis dengan Azure Command Launcher untuk Java.

Membuat kontainer aplikasi baru

Saat Anda membuat kontainer beban kerja Java untuk aplikasi baru, pertimbangkan dua hal saat memikirkan memori:

  • Memori yang dialokasikan untuk kontainer itu sendiri.
  • Jumlah memori yang tersedia untuk proses Java.

Memahami default ergonomi JVM

Aplikasi memerlukan titik awal dan pengaturan. JVM memiliki ergonomi default dengan nilai yang telah ditentukan sebelumnya yang didasarkan pada jumlah prosesor yang tersedia dan jumlah memori dalam sistem. JVM menggunakan nilai default yang diperlihatkan dalam tabel berikut saat Anda memulainya tanpa bendera atau parameter startup tertentu.

Tabel berikut ini memperlihatkan GC default untuk sumber daya yang tersedia:

Sumber daya tersedia GC bawaan
Sejumlah prosesor
Memori hingga 1.791 MB
SerialGC
2+ prosesor
Memori 1.792 MB atau lebih
G1GC

Tabel berikut menunjukkan ukuran timbunan maksimum default tergantung pada berapa banyak memori yang tersedia di lingkungan tempat JVM berjalan:

Memori tersedia Ukuran timbunan maksimum default
Hingga 256 MB 50% memori yang tersedia
256 MB hingga 512 MB ~127 MB
Lebih dari 512 MB 25% memori yang tersedia

Ukuran timbunan awal default adalah 1/64 memori yang tersedia. Nilai-nilai ini berlaku untuk OpenJDK 11 dan yang lebih baru—dan untuk sebagian besar distribusi, termasuk Microsoft Build di OpenJDK, Azul Zulu, Eclipse Temurin, Oracle OpenJDK, dan lainnya.

Menentukan memori kontainer

Pilih jumlah memori kontainer yang melayani beban kerja Anda dengan terbaik, tergantung pada kebutuhan aplikasi Anda dan pola penggunaannya yang khas. Misalnya, jika aplikasi Anda membuat grafik objek besar, Anda mungkin memerlukan lebih banyak memori daripada yang Anda butuhkan untuk aplikasi dengan banyak grafik objek kecil.

Petunjuk / Saran

Jika Anda tidak tahu berapa banyak memori yang akan dialokasikan, titik awal yang baik adalah 4 GB.

Menentukan memori tumpukan JVM

Saat Anda mengalokasikan memori heap JVM, ingatlah bahwa JVM memerlukan lebih banyak memori daripada jumlah yang dialokasikan untuk heap JVM. Jangan atur memori heap JVM maksimum agar sama dengan jumlah memori kontainer. Pengaturan ini dapat menyebabkan error kehabisan memori (OOM) pada kontainer dan kontainer mengalami crash.

Petunjuk / Saran

Alokasikan 75% memori kontainer untuk timbunan JVM.

Pada OpenJDK 11 dan yang lebih baru, atur ukuran tumpukan JVM dengan salah satu cara berikut:

Deskripsi Bendera Contoh
Nilai tetap -Xmx -Xmx4g
Nilai dinamis -XX:MaxRAMPercentage -XX:MaxRAMPercentage=75

Ukuran timbunan minimum atau awal

Jika lingkungan menjamin sejumlah memori yang dicadangkan ke instans JVM, seperti dalam kontainer, atur ukuran tumpukan minimum atau ukuran tumpukan awal ke ukuran yang sama dengan ukuran timbunan maksimum. Pengaturan ini menunjukkan kepada JVM bahwa ia tidak boleh melakukan tugas membebaskan memori ke OS.

Untuk mengatur ukuran tumpukan minimum, gunakan -Xms untuk jumlah absolut atau -XX:InitialRAMPercentage untuk jumlah persentase.

Penting

Terlepas dari apa namanya, bendera -XX:MinRAMPercentage menetapkan persentase RAM maksimum default untuk sistem dengan HINGGA 256 MB RAM yang tersedia dalam sistem.

Bagan memperlihatkan ukuran tumpukan default pada OpenJDK 17.

Tentukan GC mana yang akan digunakan

Sebelumnya, Anda menentukan jumlah memori tumpukan JVM untuk memulai. Langkah selanjutnya adalah memilih GC Anda. Jumlah maksimum memori heap JVM yang Anda miliki sering memengaruhi pilihan GC Anda. Tabel berikut menjelaskan karakteristik setiap GC.

Faktor SerialGC ParalelGC G1GC ZGC ShenandoahGC
Jumlah inti 1 2 2 2 2
Multithreaded Tidak. Ya Ya Ya Ya
Ukuran timbunan Java <4 GB <4 GB >4 GB >4 GB >4 GB
Jeda Ya Ya Ya Ya (<1 ms) Ya (<10 ms)
biaya overhead Seminimal mungkin Seminimal mungkin Menengah Menengah Menengah
Efek latensi ujung Tinggi Tinggi Tinggi Kurang Penting Menengah
Versi JDK Semua Semua JDK 8+ JDK 17+ JDK 11+
Paling cocok untuk Timbunan kecil inti tunggal Timbunan kecil multicore atau beban kerja batch dengan ukuran timbunan apa pun Responsif terhadap beban sedang hingga besar (interaksi permintaan-respons/DB) Responsif terhadap beban sedang hingga besar (interaksi permintaan-respons/DB) Responsif terhadap beban sedang hingga besar (interaksi permintaan-respons/DB)

Petunjuk / Saran

Untuk sebagian besar aplikasi layanan mikro tujuan umum, mulailah dengan GC Paralel.

Menentukan berapa banyak inti CPU yang Anda butuhkan

Untuk GC apa pun selain SerialGC, gunakan dua atau beberapa inti vCPU - atau setidaknya 2000m untuk cpu_limit di Kubernetes. Jangan pilih kurang dari satu inti vCPU pada lingkungan dalam kontainer.

Petunjuk / Saran

Jika Anda tidak tahu berapa banyak inti untuk memulai, dua inti vCPU adalah pilihan yang baik.

Pilih titik awal

Mulailah dengan dua replika atau instans di lingkungan orkestrasi kontainer seperti Kubernetes, OpenShift, Azure Spring Apps, Azure Container Apps, dan Azure App Service. Tabel berikut ini meringkas titik awal yang direkomendasikan untuk kontainerisasi aplikasi Java baru Anda.

Inti vCPU Memori kontainer Ukuran timbunan JVM GC Replika
2 4 GB 75% ParalelGC 2

Gunakan parameter JVM berikut:

-XX:+UseParallelGC -XX:MaxRAMPercentage=75

Menyetel JVM secara otomatis dengan Azure Command Launcher untuk Java

Bagian sebelumnya menjelaskan cara memilih bendera JVM secara manual berdasarkan memori kontainer, inti CPU, dan jenis beban kerja Anda. Jika Anda tidak ingin mempertahankan pengaturan ini sendiri, Azure Command Launcher untuk Java (jaz) menerapkan default JVM cloud-native secara otomatis.

Azure Command Launcher untuk Java adalah utilitas ringan yang berada di antara perintah startup Anda dan JVM. Fitur ini mendeteksi lingkungan komputasi awan, termasuk memori kontainer dan batas CPU, lalu memilih flag penyetelan yang paling sesuai untuk penentuan ukuran heap, pemilihan GC, dan diagnostik. Pendekatan ini mengurangi overhead konfigurasi dan meningkatkan pemanfaatan sumber daya di luar kotak.

Untuk menggunakan alat ini, ganti java perintah dengan jaz di skrip peluncuran atau Dockerfile Anda. Misalnya, alih-alih menyetel opsi JVM secara manual:

java -XX:+UseParallelGC -XX:MaxRAMPercentage=75 -jar myapp.jar

Gunakan jaz:

jaz -jar myapp.jar

Alat ini disertakan dalam gambar kontainer untuk Microsoft Build di OpenJDK, sehingga tidak ada pengaturan tambahan yang diperlukan. Dockerfile berikut menggunakan jaz untuk menjalankan aplikasi Java dari jar file:

# Use any Microsoft Build of OpenJDK base image
FROM mcr.microsoft.com/openjdk/jdk:25-ubuntu

# Add your application.jar
COPY application.jar /application.jar

# Use jaz to launch your Java application
CMD ["jaz", "-jar", "application.jar"]

Untuk opsi penginstalan, lingkungan yang didukung, dan detail konfigurasi, lihat Azure Command Launcher untuk Java.

Membuat kontainer aplikasi lokal yang sudah ada

Jika aplikasi Anda sudah berjalan secara lokal atau di VM di cloud, mulailah dengan konfigurasi berikut:

  • Jumlah memori yang sama yang saat ini dapat diakses oleh aplikasi.
  • Jumlah CPU atau inti vCPU yang sama yang saat ini tersedia oleh aplikasi.
  • Parameter JVM yang sama dengan yang saat ini Anda gunakan.

Jika kombinasi inti vCPU atau memori kontainer tidak tersedia, pilih yang terdekat, bulatkan inti vCPU dan memori kontainer.

Langkah selanjutnya

Sekarang setelah Anda memahami rekomendasi umum untuk kontainerisasi aplikasi Java, lanjutkan ke artikel berikut untuk menetapkan garis besar kontainerisasi dan menyederhanakan penyetelan JVM: