Pendekatan yang agak biasa apabila ia datang untuk bekerja dengan kod tanpa pelayan ialah menulisnya sebagai aplikasi Python, Node atau Go memandangkan reputasi mereka untuk permulaan sejuk yang sangat cepat.
Tetapi bagaimana jika kita berhadapan dengan apl Java sedia ada yang menyasarkan persekitaran tanpa pelayan seperti AWS Lambda? Mungkin sebahagian besar pangkalan kod kami menjadi tuan rumah Java dan kami telah membangunkan ekosistem alat dan perpustakaan yang kaya yang kami ingin gunakan semula. Menulis semula keseluruhan kumpulan aplikasi sedemikian ke dalam bahasa yang berbeza adalah mahal, apatah lagi, kami menyerahkan ciri seperti keselamatan jenis statik dan pengoptimuman masa penyusunan.
Suatu ketika dahulu, saya berdepan dengan senario tepat ini: 9 apl AWS Lambda yang ditulis dalam Java yang akan menjadi sangat perlahan pada permulaan sejuk sehingga beberapa daripadanya kadang-kadang tamat masa.
Lambdas yang dimaksudkan diletakkan di belakang Gerbang API dan digunakan untuk tugas pentadbir dengan memanggil API REST yang sepadan. Kefungsian ini tidak begitu banyak digunakan dan oleh itu mengalami permulaan yang sejuk tidak dapat dielakkan; walau bagaimanapun, kerana ini bukan perkhidmatan kritikal, ia merupakan peluang yang sesuai untuk percubaan: untuk mengetahui sama ada Lambda ini boleh diselamatkan.
Tidak lama kemudian saya terserempak dengan beberapa catatan blog lain tentang pembangun yang berjaya menggunakan GraalVM dan rangka kerja seperti Quarkus untuk menangani masalah ini. Jadi saya telah memutuskan untuk mencubanya sendiri.
Tetapi apakah alatan ini?
Ringkasnya, GraalVM ialah Mesin Maya Java yang disertakan dengan set alat yang mampu menyusun Java kepada Imej Asli dan melaksanakannya menggunakan Graal JVM.
Biasanya Java menggunakan pengkompil "Just In Time" (JIT), yang seperti namanya, melaksanakan pengoptimuman dan penyusunan semasa pelaksanaan kod kami. Aplikasi yang berjalan lama mendapat manfaat daripada ini memandangkan pengoptimum JVM sentiasa memantau pelaksanaan program dan melakukan penalaan halus yang lebih masa diterjemahkan kepada prestasi yang lebih baik.
Ini bagus jika aplikasi dibuat seketika, dan dijangka berjalan selama beberapa jam atau lebih, tetapi tidak begitu hebat jika kita berurusan dengan Kubernetes, AWS Lambdas dan kerja kelompok yang berharap untuk boot apl Java dengan cepat, berprestasi operasi dan skala sensitif masa bergantung pada permintaan - bercakap tentang lag turbo untuk peminat kereta di luar sana.
Dan di sinilah keupayaan Imej Asli GraalVM melangkah masuk untuk membantu. Daripada menggunakan pengkompil JIT, ia memilih pendekatan yang sangat berbeza untuk menyusun kod kami lebih awal daripada masa (AOT). Ia pra-membakar pai kami menggunakan analisis kod statik dan juga pra-memulakan kelas tertentu semasa masa binaan supaya ia bersedia untuk menyala pada bila-bila masa kod aplikasi kami dilaksanakan.
Hasilnya? Permulaan sejuk yang sangat pantas, yang menjadikan Imej Asli sangat berkebolehan dalam domain tanpa pelayan yang apl berumur pendek dan perlu but dengan cepat.
Satu perkara yang perlu diambil perhatian ialah walaupun GraalVM berkemampuan AOT, ia juga boleh berfungsi sebagai pengganti drop-in untuk JVM sedia ada yang menawarkan prestasi yang lebih baik memandangkan pengkompil JIT baharu GraalVM yang ditulis dalam Java.
Tetapi tunggu, ada lagi! Oleh kerana Imej Asli termasuk hanya kod yang berada pada laluan pelaksanaan yang diketahui, kami memangkas lemak dan semua kelas Java yang belum diisytiharkan secara eksplisit untuk disimpan tidak akan tersedia. Oleh kerana kami hanya menyimpan bit yang dijangka akan dilaksanakan, kami meningkatkan keselamatan aplikasi kami.
Ambil contoh kelemahan Log4J yang terkenal yang menggunakan Pelaksanaan Kod Jauh sebagai cara untuk menjejaskan hos. Dengan Imej Asli, rantaian alat sangat tidak mungkin berjaya kerana kepingan kod perpustakaan yang diperlukan untuk menyampaikan serangan itu tidak dapat dicapai.
Quarkus sebaliknya, ialah rangka kerja Java yang dioptimumkan untuk aplikasi tanpa pelayan yang disertakan dengan kotak alat yang memudahkan pembinaan Imej Asli dengan menawarkan sambungan untuk mengkonfigurasi dan membina AWS Lambdas secara khusus sebagai boleh laku asli.
Semasa perjalanan pengoptimuman Lambda saya, saya juga telah menemui teknik pengoptimuman alternatif. Salah satu daripada pengoptimuman tersebut ialah penggunaan eksklusif pengkompil C1 yang dicadangkan semasa pelaksanaan Lambda yang telah berjanji untuk menyampaikan permulaan sejuk yang lebih cepat. Biasanya, aplikasi Java yang dijalankan di dalam JVM menggunakan kompilasi berperingkat yang terdiri daripada C1 yang lebih pantas, tetapi kurang optimum, diikuti oleh C2 yang lebih perlahan, tetapi menawarkan prestasi yang lebih optimum untuk apl Java yang dilaksanakan untuk masa yang lama. Memandangkan Lambdas berumur pendek, faedah kompilasi C2 boleh diabaikan.
Panduan berjalan melalui proses mengkonfigurasi kompilasi C1 untuk AWS Lambdas tersedia di sini.
Sudah tentu saya ingin tahu berapa banyak peningkatan yang boleh ditawarkan oleh teknik ini berbanding dengan pelan induk GraalVM saya yang sedia ada, jadi saya juga telah memasukkannya ke dalam penemuan saya di bawah.
Butiran lanjut tentang kompilasi berperingkat JVM serta pengkompil JIT serba baharu GraalVM boleh didapati dalam artikel Baeldung ini.
Ironisnya, beberapa bulan selepas saya menghantar perubahan saya kepada pengeluaran, AWS menghasilkan keupayaan SnapStart terbaharu mereka, yang mengambil gambar Lambda yang sedang berjalan dan bukannya memulakannya semula sekali lagi, ia menggunakan imej syot kilat sebagai titik pemulihan menjanjikan permulaan sejuk yang lebih cepat. Saya terpaksa mencubanya untuk mengetahui sama ada penggunaan GraalVM adalah satu usaha yang sia-sia dan juga memasukkannya dalam penemuan saya.
Perlu diingat bahawa untuk memanfaatkan SnapStart sepenuhnya, pemfaktor semula kod diperlukan untuk menggunakan cangkuk beforeCheckpoint dan afterRestore (butiran lanjut di sini). Memandangkan saya ingin mengelakkan sebarang perubahan kod utama jika boleh, saya telah menggunakan ciri ini "seadanya", tanpa melaksanakan kaedah ini dan menyusun semula sebarang kod.
Kini kembali ke GraalVM! Saya terkejut, selepas memasukkan penyelesaian ini, tiada perubahan kod Java sama sekali diperlukan selain daripada menambah dan melaraskan fail konfigurasi binaan dan beberapa metadata yang diperlukan.
Bunyi terlalu bagus untuk menjadi kenyataan?
Mungkin sedikit. Memandangkan kami menggunakan kompilasi AOT, dalam dunia Java, ini menimbulkan cabaran tertentu jika melibatkan penggunaan ciri bahasa seperti Reflections, Proxies, Interfaces dan Service registry yang banyak bergantung kepada perpustakaan. Inilah sebabnya mengapa pengkompil GraalVM memerlukan metadata konfigurasi tambahan untuk diisytiharkan yang secara eksplisit mendaftarkan kelas dan perkhidmatan tertentu supaya mereka boleh dimasukkan ke dalam artifak akhir. GraalVM menyediakan apa yang dipanggil ejen yang boleh digunakan untuk berjalan bersama boleh laku anda untuk mengenal pasti secara automatik konfigurasi yang diperlukan yang boleh menjadikan proses ini lebih mudah.
Quarkus menyediakan beberapa sambungan untuk perpustakaan terkenal untuk menjadikannya "mesra imej asli", tetapi memandangkan saya bekerja dengan pangkalan kod sedia ada, dan matlamat saya adalah untuk mengelakkan sebarang refactor utama (atau sebarang perubahan kod dalam perkara itu ), saya memutuskan untuk mencipta fail konfigurasi yang diperlukan yang diperlukan oleh perpustakaan sedia ada untuk menghasilkan Imej Asli dengan jayanya.
Berhati-hati bahawa penyusunan Imej Asli adalah intensif sumber dan ia mengambil masa yang jauh lebih lama berbanding kompilasi kod bait yang menyasarkan masa jalan JVM standard. Kemungkinannya ialah anda mungkin mendapati diri anda terpaksa memperuntukkan lebih banyak RAM kepada nod binaan untuk mengelakkan masalah ingatan, yang tidak sepatutnya menjadi pemecah perjanjian, tetapi pastinya sesuatu yang perlu diingat.
Sekarang saya telah mengumpulkan Lambdas Imej Asli saya dan dibungkus, tiba masanya untuk menggunakan ia ke dalam persekitaran ujian. Biasanya, Java Lambdas menggunakan Java Runtimes AWS untuk dilaksanakan; walau bagaimanapun, memandangkan kami cuba menggunakan Imej Asli yang merupakan artifak binari yang mengandungi kod apl kami yang dibalut di dalam Graal JVM, kami mesti memilih salah satu daripada persekitaran Amazon Linux "Tersuai" yang ditawarkan oleh AWS.
Saya telah menggunakan Koleksi API Posmen untuk menghantar permintaan kepada semua 9 Lambda dan mengukur masa tindak balas mula sejuk untuk setiap teknik yang dinyatakan di atas. Untuk memastikan saya sentiasa mengalami permulaan yang sejuk, saya telah memuatkan semula konfigurasi Lambda sasaran yang memastikan bahawa seruan seterusnya tidak akan menggunakan contoh yang mungkin sudah hangat. Semua Lambdas telah dikonfigurasikan dengan 1GB RAM. Saya juga telah mengukur satu doa untuk setiap konfigurasi memandangkan proses itu memakan masa; namun, masa tindak balas yang diperhatikan memberikan gambaran yang cukup jelas.
Jadi adakah ia berjaya? Sudah tentu! Berikut adalah keputusannya:
Dan pemenang yang jelas ialah: GraalVM Native Images - secara purata, ia telah menghasilkan kelajuan 3x ganda berbanding dengan Java Lambdas yang tidak berubah - tiada lagi masa tamat, dan masa tindak balas yang lebih baik, itulah yang saya mahukan capai.
SnapStart tidak berprestasi sebaik yang saya fikirkan tanpa sebarang perubahan kod. Apabila pengkompil C1 digunakan sebagai tambahan kepada ciri SnapStart, ia mengurangkan masa mula sejuk lebih jauh, tetapi masih tidak mengalahkan Imej Asli GraalVM. Itu bukan untuk mengatakan bahawa ia bukan pilihan yang berdaya maju sebagai penambahbaikan yang cepat dan mudah untuk dilaksanakan; walau bagaimanapun, jika kami ingin mengoptimumkan Lambda kami sebanyak mungkin dan kami mempunyai sedikit masa dan sumber untuk melaraskan konfigurasi dan proses binaan kami, GraalVM pastinya lebih unggul dalam hal prestasi dan keselamatan.
Seperti yang didakwa oleh GraalVM, Native Images memerlukan kurang sumber untuk dijalankan dengan berkesan berbanding rakan JVM biasa mereka. Saya ingin melihat bagaimana prestasi permulaan sejuk dan permulaan hangat akan bertahan jika saya ingin mengurangkan jumlah RAM yang perlu digunakan oleh Lambdas ini. Kali ini saya telah memilih hanya satu apl Lambda untuk melakukan ujian ini. Berikut adalah keputusannya:
Dan pada janji mereka mereka telah menunaikan! JVM Lambdas biasa kehabisan memori apabila mencuba konfigurasi 256 MB dan lebih rendah, manakala Imej Asli kelihatan tidak berfasa dan terus dilaksanakan. Jika bukan kerana 128 MB sebagai pilihan memori yang tersedia paling rendah, saya tertanya-tanya berapa banyak yang boleh kita lakukan. Imej Asli bukan sahaja lebih pantas pada permulaan sejuk, tetapi menawarkan prestasi yang konsisten apabila bekerja dengan sumber terhad, yang diterjemahkan kepada kos operasi yang lebih rendah.
Ekosistem Java kaya dan luas dengan banyak teknologi baharu dan peningkatan yang muncul setiap hari yang mengekalkan Java dalam permainan apabila ia berkaitan dengan aplikasi tanpa pelayan. Salah satu teknologi baru muncul ialah GraalVM. Apa yang bermula sebagai projek penyelidikan kini perlahan-lahan diterima pakai dan menjadi alternatif yang berdaya maju kepada JVM standard seperti HotSpot. Dalam catatan blog ini, saya hampir tidak menconteng apa yang GraalVM tawarkan dan saya akan menggalakkan pembaca untuk menerokainya dengan lebih lanjut. Terdapat beberapa kisah kejayaan daripada syarikat seperti Adyen (pautan artikel) atau Facebook (pautan artikel) yang dapat menggunakan GraalVM untuk menjimatkan masa dan wang.
Jadi pada kali seterusnya anda akan memberikan diskaun kepada Java sebagai pilihan, cuba GraalVM. Dan kini Spring Boot 3 menyokong Imej Asli GraalVM di luar kotak, lebih mudah berbanding sebelum ini untuk menggunakannya untuk beban kerja tanpa pelayan anda untuk memanfaatkan prestasi, penggunaan sumber yang rendah dan keselamatan tambahan yang ditawarkan oleh GraalVM.
Atas ialah kandungan terperinci Java Juga Boleh Tanpa Pelayan: Menggunakan GraalVM untuk Permulaan Dingin Pantas. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!