Bagaimana Quarkus Menggabungkan Pemrograman Imperatif dan Reaktif

Tahun ini kami berencana untuk secara serius mengembangkan tema kontainer, Cloud-Native Java dan Kubernetes . Kelanjutan logis dari topik ini adalah cerita tentang kerangka kerja Quarkus, yang sudah dipertimbangkan di Habré. Artikel hari ini tidak terlalu berfokus pada “perangkat Java ultra cepat subatomik” seperti perspektif yang dibawa Quarkus ke Enterprise. (Ngomong-ngomong, daftarkan dan buka webinar kami " Ini adalah Quarkus - kerangka kerja asli Kubernetes Jawa ", yang akan diadakan pada 27 Mei. Kami akan menunjukkan cara memulai dari awal atau mentransfer solusi yang sudah jadi)



Java dan JVM masih sangat populer, tetapi ketika bekerja dengan teknologi tanpa server dan layanan berbasis cloud, Java dan bahasa lain untuk JVM semakin jarang digunakan, karena mereka mengambil terlalu banyak ruang memori dan memuat terlalu lambat, yang membuat mereka tidak cocok untuk gunakan dengan wadah yang berumur pendek. Untungnya, situasi ini saat ini mulai berubah berkat Quarkus.

Java subatom ultrafast telah mencapai tingkat baru!


42 rilis, 8 bulan kerja komunitas dan 177 pengembang luar biasa - hasil dari semuanya adalah rilis pada November 2019 dari Quarkus 1.0 , rilis yang menandai tonggak penting dalam pengembangan proyek dan menawarkan banyak fitur dan kemampuan keren (lebih banyak tentang mereka dapat ditemukan dalam pengumuman ) .

Hari ini kita akan menceritakan bagaimana Quarkus menggabungkan model pemrograman imperatif dan reaktif berdasarkan pada inti reaktif tunggal. Kami akan mulai dengan penyimpangan singkat ke dalam sejarah dan kemudian melihat lebih dekat pada apa inti dual dari Quarkus bereaksi dan bagaimana pengembang Java dapat mengambil keuntungan dari ini.

Mikroservisy , arsitektur berbasis event dan serverless-fungsi - semua hari ini, seperti yang mereka katakan, sedang meningkat. Baru-baru ini, penciptaan arsitektur berbasis cloud telah menjadi jauh lebih sederhana dan lebih terjangkau, tetapi masalah tetap ada - terutama untuk pengembang Java. Misalnya, dalam hal fungsi tanpa server dan layanan microser, ada kebutuhan mendesak untuk mengurangi waktu startup, mengurangi konsumsi memori dan membuat pengembangannya lebih nyaman dan menyenangkan. Java dalam beberapa tahun terakhir telah membuat beberapa peningkatan, seperti fungsi ergonomis yang dimodifikasi untuk kontainer, dan sebagainya. Namun, mendapatkan Java untuk bekerja di wadah masih tidak mudah. Oleh karena itu, kita akan mulai dengan melihat beberapa kompleksitas intrinsik Jawa, yang sangat akut ketika mengembangkan aplikasi Java yang berorientasi pada wadah.

Pertama, mari kita beralih ke ceritanya.


Aliran dan wadah


Dimulai dengan versi 8u131, Java memiliki lebih atau kurang wadah yang didukung karena peningkatan fungsionalitas ergonomi. Secara khusus, JVM sekarang tahu berapa banyak core prosesor yang digunakannya, dan dapat dengan benar mengkonfigurasi thread pools - biasanya fork / join pools. Tentu saja, ini hebat, tetapi katakanlah kita memiliki aplikasi web tradisional yang menggunakan HTTP servlets dan berjalan di Tomcat, Jetty, dan sebagainya. Akibatnya, aplikasi ini akan memberikan masing-masing permintaan aliran terpisah dan memungkinkannya untuk memblokir aliran ini sambil menunggu operasi I / O, misalnya, ketika mengakses database, file atau layanan lainnya. Artinya, ukuran aplikasi semacam itu tidak tergantung pada jumlah core yang tersedia, tetapi pada jumlah permintaan simultan. Selain itu, ini berarti kuota atau batas dalam Kubernet dengan jumlah inti tidak akan membantu di sini,dan kesepakatan akan berakhir berlari.

Kehabisan memori


Streaming adalah memori. Dan pembatasan memori intra-kontainer tidak berarti obat mujarab. Mulailah menambah jumlah aplikasi dan utas, dan cepat atau lambat Anda akan menghadapi peningkatan kritis dalam frekuensi switching dan, sebagai akibatnya, dengan penurunan kinerja. Selain itu, jika aplikasi menggunakan kerangka kerja layanan mikro tradisional atau menghubungkan ke database, atau menggunakan caching, atau entah bagaimana mengkonsumsi memori, Anda benar-benar membutuhkan alat yang memungkinkan Anda untuk melihat ke dalam JVM dan melihat bagaimana mengelola memori, dan tidak membunuh JVM sendiri (mis. XX: + UseCGroupMemoryLimitForHeap). Dan terlepas dari kenyataan bahwa, dimulai dengan Java 9, JVM telah belajar untuk menerima cgroup dan beradaptasi sesuai itu, membuat cadangan dan mengelola memori tetap merupakan urusan yang agak rumit.

Kuota dan batas


Java 11 memperkenalkan dukungan untuk kuota CPU (seperti PreferContainerQuotaForCPUCount). Kubernetes juga menawarkan dukungan batas dan kuota. Ya, semua ini masuk akal, tetapi jika aplikasi kembali melampaui kuota yang dialokasikan, kami kembali sampai pada kesimpulan bahwa ukuran - seperti halnya dengan aplikasi Java tradisional - ditentukan oleh jumlah inti dan dengan alokasi utas terpisah untuk setiap permintaan, kemudian ada sedikit akal dalam semua ini.
Selain itu, jika Anda menggunakan kuota dan batas atau fungsi penskalaan horizontal (skala-out) dari platform yang mendasari Kubernetes, masalahnya juga tidak menyelesaikannya sendiri. Kami hanya menghabiskan lebih banyak sumber daya untuk menyelesaikan masalah asli atau, sebagai hasilnya, kami akhirnya menggunakan sumber daya. Dan jika itu adalah sistem yang sangat dimuat dalam cloud publik, kita hampir pasti akan mulai menggunakan lebih banyak sumber daya daripada yang benar-benar dibutuhkan.

Dan apa yang harus dilakukan dengan semua ini?


Jika dengan cara yang sederhana, gunakan pustaka dan kerangka kerja I / O asinkron dan non-pemblokiran seperti Netty, Vert.x atau Akka. Mereka jauh lebih cocok untuk bekerja dalam wadah karena sifat reaktifnya. Berkat non-pemblokiran I / O, utas yang sama dapat memproses beberapa permintaan secara bersamaan. Sementara satu permintaan sedang menunggu hasil I / O, utas pemrosesan dibebaskan dan diambil untuk permintaan lainnya. Dan ketika hasil I / O akhirnya tiba, pemrosesan permintaan pertama berlanjut. Dengan mengganti pemrosesan permintaan dalam aliran yang sama, Anda dapat mengurangi jumlah utas dan mengurangi konsumsi sumber daya untuk memproses permintaan.

Dengan I / O non-blocking, jumlah core menjadi parameter kunci, karena menentukan jumlah I / O thread yang dapat berjalan secara paralel. Ketika digunakan dengan benar, ini memungkinkan Anda untuk mendistribusikan beban secara efektif antara inti dan mengatasi beban yang lebih tinggi dengan sumber daya yang lebih sedikit.

Bagaimana, dan hanya itu saja?


Tidak, ada satu hal lagi. Pemrograman reaktif membantu memanfaatkan sumber daya dengan lebih baik, tetapi juga ada harganya. Secara khusus, kode harus ditulis ulang sesuai dengan prinsip-prinsip non-pemblokiran dan menghindari pemblokiran aliran input-output. Dan ini adalah model pengembangan dan implementasi yang sangat berbeda. Dan meskipun ada banyak perpustakaan yang bermanfaat, ini masih merupakan perubahan utama dalam cara berpikir yang biasa.

Pertama, Anda perlu belajar cara menulis kode yang berjalan secara tidak sinkron. Segera setelah Anda mulai menggunakan I / O yang tidak menghalangi, Anda harus secara eksplisit menentukan apa yang harus terjadi ketika Anda menerima respons terhadap permintaan tersebut. Hanya memblokir dan menunggu akan gagal. Sebagai gantinya, Anda dapat melewati panggilan balik, menggunakan pemrograman reaktif, atau kelanjutan. Tapi itu tidak semua: untuk menggunakan I / O non-blocking, Anda membutuhkan server dan klien non-blocking, dan lebih disukai di mana-mana. Dalam hal HTTP, semuanya sederhana, tetapi ada juga database, dan sistem file, dan banyak lagi.

Walaupun reaktivitas ujung-ke-ujung total memberi efisiensi maksimum, perubahan semacam itu bisa sulit dicerna dalam praktiknya. Oleh karena itu, kemampuan untuk menggabungkan kode reaktif dan imperatif menjadi syarat yang diperlukan untuk:

  1. Secara efektif menggunakan sumber daya di area yang paling banyak dimuat dalam sistem perangkat lunak;
  2. Gunakan kode gaya yang lebih sederhana di bagian lainnya.

Memperkenalkan Quarkus


Sebenarnya, ini adalah inti dari Quarkus - untuk menggabungkan model reaktif dan imperatif dalam satu lingkungan runtime.

Quarkus didasarkan pada Vert.x dan Netty, di atasnya sejumlah kerangka kerja dan ekstensi reaktif digunakan untuk membantu pengembang. Quarkus dirancang untuk membangun tidak hanya layanan HTTP mikro, tetapi juga arsitektur yang digerakkan oleh peristiwa. Karena sifatnya yang reaktif, ia bekerja sangat efisien dengan sistem pengiriman pesan (Apache Kafka, AMQP, dll.).

Kuncinya adalah bagaimana menggunakan mesin jet yang sama untuk kode imperatif dan reaktif.



Quarkus melakukannya dengan cemerlang. Pilihan antara imperatif dan reaktif sudah jelas - menggunakan inti reaktif yang satu dan yang lainnya. Dan dengan apa yang sangat membantu, itu dengan kode non-pemblokiran cepat yang memproses hampir semua yang melewati thread loop acara (event-loop thread, alias IO thread). Tetapi jika Anda memiliki REST klasik atau aplikasi sisi klien, Quarkus siap untuk model pemrograman yang penting. Misalnya, dukungan HTTP di Quarkus didasarkan pada penggunaan mesin jet dan non-blocking (Eclipse Vert.x dan Netty). Semua permintaan HTTP yang diterima oleh aplikasi Anda terlebih dahulu melewati loop acara (IO Thread), dan kemudian dikirim ke bagian kode yang mengelola permintaan.Bergantung pada tujuannya, kode kontrol permintaan dapat dipanggil dalam utas terpisah (disebut utas pekerja, digunakan dalam kasus servlet dan Jax-RS) atau menggunakan aliran input-output asli (rute reaktif rute reaktif).



Klien yang tidak memblokir yang bekerja di atas mesin Vert.x digunakan untuk konektor sistem pengiriman pesan. Oleh karena itu, Anda dapat secara efisien mengirim, menerima, dan memproses pesan dari sistem kelas pesan middleware.

Situs Quarkus.io mengumpulkan beberapa panduan bagus untuk membantu Anda memulai dengan Quarkus:


Selain itu, kami telah menyiapkan pelajaran praktis online untuk membiasakan diri dengan berbagai aspek pemrograman reaktif, apalagi, hanya browser yang cukup untuk menyelesaikannya, tidak diperlukan IDE untuk ini, dan komputer tidak diperlukan. Temukan pelajaran ini di sini .

Sumber daya yang bermanfaat




10 tutorial video Quarkus agar terbiasa dengan topik tersebut


Menurut situs web Quarkus.io , Quarkus adalah tumpukan Java berorientasi Kubernetes yang dirancang untuk GraalVM dan OpenJDK HotSpot dan disusun dari perpustakaan dan standar Java terbaik.

Untuk membantu Anda memahami topik, kami telah memilih 10 tutorial video yang mencakup berbagai aspek Quarkus dan contoh penggunaannya:

1. Memperkenalkan Quarkus: Kerangka Java Generasi Selanjutnya untuk Kubernetes


Penulis: Thomas Qvarnstrom dan Jason Greene
Tujuan dari proyek Quarkus adalah untuk menciptakan platform Java untuk Kubernetes dan lingkungan tanpa server, dan menggabungkan model pemrograman reaktif dan imperatif ke dalam runtime tunggal sehingga pengembang secara fleksibel dapat memvariasikan pendekatan ketika bekerja dengan berbagai arsitektur aplikasi terdistribusi. Pelajari lebih lanjut dari kuliah pengantar di bawah ini.



2. Quarkus: Jawa subatom ultrafast


Penulis: Burr Sutter
Tutorial video dari kuliah online DevNation Live menunjukkan cara menggunakan Quarkus untuk mengoptimalkan aplikasi Java perusahaan, API, layanan mikro, dan fitur tanpa server di Kubernetes / OpenShift, menjadikannya jauh lebih kecil, lebih cepat, dan lebih dapat diskalakan.



3. Quarkus dan GraalVM: kami mempercepat Hibernate ke kecepatan super dan menekan ke ukuran subatomik


Penulis: Sane Grinovero
Dari presentasi Anda akan belajar bagaimana Quarkus muncul, cara kerjanya, dan bagaimana memungkinkan Anda membuat perpustakaan yang rumit seperti Hibernate ORM yang kompatibel dengan gambar asli GraalVM.



4. Belajar mengembangkan aplikasi tanpa server


Diposting oleh Marthen Luther
Video di bawah ini menunjukkan cara membuat aplikasi Java sederhana menggunakan Quarkus dan menyebarkannya sebagai aplikasi tanpa server di Knative.



5. Quarkus: kode dengan senang hati


Diposting oleh Edson
Yanaga Wideguide untuk membuat proyek Quarkus pertama Anda untuk memahami mengapa Quarkus memenangkan hati para pengembang.



6. Java dan kontainer - apa yang akan menjadi masa depan bersama mereka


Diposting oleh Mark Little
Presentasi ini memperkenalkan sejarah Jawa dan menjelaskan mengapa Quarkus adalah masa depan Jawa.



7. Quarkus: Jawa subatom ultrafast


Penulis: Dimitris Andreadis Dimitris Andreadis
Tinjauan umum tentang pengembang Quarkus yang terkenal: kesederhanaan, kecepatan sangat cepat, perpustakaan dan standar terbaik.



8. Quarkus dan sistem reaktif subatomik


Diposting oleh Clement Escoffier
Melalui integrasi dengan GraalVM, Quarkus memberikan pengalaman pengembangan super cepat dan runtime subatomik. Penulis berbicara tentang sisi reaktif Quarkus dan bagaimana menggunakannya ketika membuat aplikasi reaktif dan aplikasi streaming.



9. Quarkus dan pengembangan aplikasi cepat di Eclipse MicroProfile


Diposting oleh John Clingan Dengan
menggabungkan Eclipse MicroProfile dan Quarkus, pengembang dapat membuat aplikasi wadah MicroProfile berfungsi penuh yang berjalan dalam beberapa puluh milidetik. Video merinci cara menyandikan aplikasi wadah MicroProfile untuk ditempatkan di platform Kubernetes.



10. Java, Versi Turbo


Diposting oleh Marcus Biel
Penulis menunjukkan bagaimana menggunakan Quarkus untuk membuat wadah Java super-kecil dan super cepat untuk terobosan nyata, terutama di lingkungan tanpa server.


All Articles