Bagaimana Quarkus menggabungkan pemrograman imperatif dan reaktif

Tahun ini kami berencana serius mengembangkan tema container, Java Cloud-Asli ΠΈ Kubernetes. Kelanjutan logis dari topik ini adalah cerita tentang kerangka Quarkus dipertimbangkan di HabrΓ©. Artikel hari ini tidak membahas tentang desain "Java supercepat subatomik" dan lebih banyak membahas tentang janji yang dibawa Quarkus ke Enterprise.

Bagaimana Quarkus menggabungkan pemrograman imperatif dan reaktif

Java dan JVM masih sangat populer, namun ketika bekerja dengan teknologi tanpa server dan layanan mikro cloud-native, Java dan bahasa JVM lainnya semakin jarang digunakan karena memakan terlalu banyak ruang memori dan memuat terlalu lambat, sehingga membuat mereka kurang cocok untuk digunakan dengan wadah berumur pendek. Beruntungnya, situasi tersebut kini mulai berubah berkat Quarkus.

Java subatomik supercepat telah mencapai level baru!

42 rilis, 8 bulan kerja komunitas, dan 177 pengembang luar biasa - hasil dari semuanya adalah rilis pada November 2019 Kuarkus 1.0, rilis yang menandai tonggak penting dalam pengembangan proyek dan menawarkan banyak fitur dan kemampuan keren (Anda dapat membaca lebih lanjut tentangnya di pengumuman).

Hari ini kami akan menunjukkan kepada Anda bagaimana Quarkus menggabungkan model pemrograman imperatif dan reaktif menjadi satu inti reaktif. Kita akan mulai dengan sejarah singkat dan kemudian membahas secara rinci tentang apa itu dualisme inti reaktif Quarkus dan bagaimana caranya Jawa-Pengembang dapat memanfaatkan manfaat ini.

Layanan mikro, arsitektur yang digerakkan oleh peristiwa ΠΈ tanpa server-fungsi – semua ini, seperti yang mereka katakan, sedang meningkat saat ini. Baru-baru ini, pembuatan arsitektur cloud-centric menjadi lebih mudah dan lebih mudah diakses, namun permasalahan tetap ada - terutama bagi pengembang Java. Misalnya, dalam hal fungsi tanpa server dan layanan mikro, terdapat kebutuhan mendesak untuk mengurangi waktu startup, mengurangi konsumsi memori, dan tetap membuat pengembangannya lebih nyaman dan menyenangkan. Java telah melakukan beberapa perbaikan dalam beberapa tahun terakhir, seperti peningkatan fungsi ergonomis untuk container dan sebagainya. Namun, membuat Java berfungsi dengan baik di dalam container masih merupakan tantangan. Jadi kita akan mulai dengan melihat beberapa kompleksitas inheren Java, yang sangat penting ketika mengembangkan aplikasi Java berorientasi container.

Pertama, mari kita lihat sejarah.

Bagaimana Quarkus menggabungkan pemrograman imperatif dan reaktif

Aliran dan kontainer

Dimulai dengan versi 8u131, Java mulai kurang lebih mendukung container karena peningkatan fungsionalitas ergonomis. Secara khusus, JVM sekarang mengetahui berapa banyak inti prosesor yang dijalankannya dan dapat mengonfigurasi kumpulan threadβ€”biasanya kumpulan fork/joinβ€”sesuai dengan itu. Tentu saja ini bagus, tetapi katakanlah kita memiliki aplikasi web tradisional yang menggunakan servlet HTTP dan berjalan di Tomcat, Jetty, dll. Akibatnya, aplikasi ini akan memberikan setiap permintaan thread terpisah dan mengizinkannya memblokir thread ini sambil menunggu operasi I/O, misalnya saat mengakses database, file, atau layanan lainnya. Artinya, ukuran aplikasi semacam itu tidak bergantung pada jumlah inti yang tersedia, namun pada jumlah permintaan simultan. Selain itu, ini berarti bahwa kuota atau batasan jumlah inti di Kubernetes tidak akan banyak membantu di sini, dan masalah ini pada akhirnya akan berakhir dengan pembatasan.

Kelelahan memori

Utas adalah memori. Dan keterbatasan memori intra-kontainer bukanlah obat mujarab. Mulailah meningkatkan jumlah aplikasi dan thread, dan cepat atau lambat Anda akan mengalami peningkatan frekuensi peralihan yang signifikan dan, sebagai akibatnya, penurunan kinerja. Selain itu, jika aplikasi Anda menggunakan kerangka kerja layanan mikro tradisional, atau terhubung ke database, atau menggunakan caching, atau menghabiskan memori, Anda jelas memerlukan alat yang memungkinkan Anda melihat ke dalam JVM dan melihat cara JVM mengelola memori tanpa mematikannya. JVM itu sendiri (misalnya, XX:+UseCGroupMemoryLimitForHeap). Dan meskipun, sejak Java 9, JVM telah belajar menerima cgroup dan beradaptasi, menyimpan dan mengelola memori tetap menjadi masalah yang rumit.

Kuota dan batasan

Java 11 memperkenalkan dukungan untuk kuota CPU (seperti PreferContainerQuotaForCPUCount). Kubernetes juga menawarkan dukungan untuk batasan dan kuota. Ya, ini semua masuk akal, tetapi jika aplikasi kembali melebihi kuota yang dialokasikan, kita akan mendapatkan ukuran lagi - seperti halnya aplikasi Java tradisional - ditentukan oleh jumlah inti dan alokasi thread terpisah untuk masing-masingnya. permintaan, maka semua ini tidak ada gunanya.
Selain itu, jika Anda menggunakan kuota dan batasan atau fungsi perluasan skala dari platform yang mendasari Kubernetes, masalahnya juga tidak akan terselesaikan dengan sendirinya. Kita hanya menghabiskan lebih banyak sumber daya untuk memecahkan masalah awal atau malah mengeluarkan uang berlebihan. Dan jika itu adalah sistem dengan beban tinggi di cloud publik, kita hampir pasti akan menggunakan lebih banyak sumber daya daripada yang sebenarnya kita perlukan.

Dan apa hubungannya dengan semua ini?

Sederhananya, gunakan pustaka dan kerangka kerja I/O asinkron dan non-pemblokiran seperti Netty, Vert.x atau Akka. Mereka lebih cocok bekerja di dalam kontainer karena sifatnya yang reaktif. Berkat I/O non-pemblokiran, thread yang sama dapat memproses beberapa permintaan secara bersamaan. Saat satu permintaan menunggu hasil I/O, thread yang memprosesnya dilepaskan dan diambil alih oleh permintaan lain. Dan ketika hasil I/O akhirnya tiba, pemrosesan permintaan pertama dilanjutkan. Dengan menyisipkan pemrosesan permintaan dalam thread yang sama, Anda dapat mengurangi jumlah total thread dan mengurangi konsumsi sumber daya untuk memproses permintaan.

Dengan I/O non-blocking, jumlah core menjadi parameter kunci karena menentukan jumlah thread I/O yang dapat dieksekusi secara paralel. Jika digunakan dengan benar, ini memungkinkan Anda mendistribusikan beban antar inti secara efektif dan menangani beban kerja yang lebih tinggi dengan sumber daya yang lebih sedikit.

Bagaimana, itu saja?

Tidak, ada hal lain. Pemrograman reaktif membantu memanfaatkan sumber daya dengan lebih baik, namun juga ada konsekuensinya. Secara khusus, kode harus ditulis ulang sesuai dengan prinsip non-pemblokiran dan menghindari pemblokiran thread I/O. Dan ini adalah model pengembangan dan pelaksanaan yang sangat berbeda. Dan meskipun ada banyak perpustakaan yang berguna di sini, ini masih merupakan perubahan radikal dalam cara berpikir kita yang biasa.

Pertama, Anda perlu mempelajari cara menulis kode yang berjalan secara asinkron. Setelah Anda mulai menggunakan I/O non-pemblokiran, Anda perlu secara eksplisit menentukan apa yang harus terjadi ketika respons terhadap permintaan diterima. Memblokir dan menunggu saja tidak akan berfungsi lagi. Sebagai gantinya, Anda dapat meneruskan panggilan balik, menggunakan pemrograman reaktif, atau kelanjutan. Namun bukan itu saja: untuk menggunakan I/O non-pemblokiran, Anda memerlukan server dan klien non-pemblokiran, sebaiknya di mana saja. Dalam kasus HTTP, semuanya sederhana, tetapi ada juga database, sistem file, dan banyak lagi.

Meskipun reaktivitas total end-to-end memaksimalkan efisiensi, perubahan seperti itu mungkin sulit dilakukan dalam praktiknya. Oleh karena itu, kemampuan menggabungkan kode reaktif dan imperatif menjadi prasyarat untuk:

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

Memperkenalkan Quarkus

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

Quarkus didasarkan pada Vert.x dan Netty, dengan serangkaian kerangka kerja reaktif dan ekstensi untuk membantu pengembang. Quarkus dirancang untuk membangun tidak hanya layanan mikro HTTP, tetapi juga arsitektur berbasis peristiwa. Karena sifatnya yang reaktif, ia bekerja sangat efektif dengan sistem pesan (Apache Kafka, AMQP, dll.).

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

Bagaimana Quarkus menggabungkan pemrograman imperatif dan reaktif

Quarkus melakukan ini dengan cemerlang. Pilihan antara imperatif dan reaktif sudah jelas - gunakan kernel reaktif untuk keduanya. Yang benar-benar membantu adalah kode cepat dan non-pemblokiran yang menangani hampir semua hal yang melewati thread loop peristiwa, alias thread IO. Namun jika Anda memiliki REST klasik atau aplikasi sisi klien, Quarkus telah menyiapkan model pemrograman penting. Misalnya, dukungan HTTP di Quarkus didasarkan pada penggunaan mesin non-pemblokiran dan reaktif (Eclipse Vert.x dan Netty). Semua permintaan HTTP yang diterima oleh aplikasi Anda terlebih dahulu diteruskan melalui loop peristiwa (IO Thread) dan kemudian dikirim ke bagian kode yang mengelola permintaan tersebut. Tergantung pada tujuannya, kode manajemen permintaan dapat dipanggil dalam thread terpisah (yang disebut thread pekerja, digunakan dalam kasus servlet dan Jax-RS) atau menggunakan thread I/O sumber (rute reaktif).

Bagaimana Quarkus menggabungkan pemrograman imperatif dan reaktif

Konektor sistem pesan menggunakan klien non-pemblokiran yang berjalan di atas mesin Vert.x. Oleh karena itu, Anda dapat mengirim, menerima, dan memproses pesan secara efektif dari sistem middleware perpesanan.

Situs ini Quarkus.io Berikut beberapa tutorial bagus untuk membantu Anda memulai Quarkus:

Kami juga telah membuat tutorial praktis online untuk mengajari Anda berbagai aspek pemrograman reaktif hanya dalam browser, tidak memerlukan IDE, dan tidak memerlukan komputer. Anda dapat menemukan pelajaran ini di sini.

Sumber daya yang berguna

10 video pelajaran tentang Quarkus untuk mengenal topik tersebut

Seperti yang mereka katakan di situs web Quarkus.io, kuarkus - adalah KubernetesTumpukan Java berorientasi, disesuaikan untuk GraalVM dan OpenJDK HotSpot dan dirakit dari perpustakaan dan standar Java terbaik.

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

1. Memperkenalkan Quarkus: Kerangka Java Generasi Selanjutnya untuk Kubernetes

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

2. Quarkus: Java Subatomik Supercepat

Oleh: Burr Sutter
Video tutorial dari DevNation Live ini mendemonstrasikan cara menggunakan Quarkus untuk mengoptimalkan aplikasi Java perusahaan, API, layanan mikro, dan fungsi tanpa server di lingkungan Kubernetes/OpenShift, menjadikannya jauh lebih kecil, lebih cepat, dan lebih skalabel.

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

Pengarang: Sanne Grinovero
Dari presentasi ini Anda akan mempelajari bagaimana Quarkus terbentuk, cara kerjanya, dan bagaimana Quarkus memungkinkan Anda membuat perpustakaan yang kompleks, seperti Hibernate ORM, yang kompatibel dengan gambar GraalVM asli.

4. Belajar mengembangkan aplikasi tanpa server

Pengarang: Martin Luther
Video di bawah ini menunjukkan cara membuat aplikasi Java sederhana menggunakan Quarkus dan menerapkannya sebagai aplikasi tanpa server di Knative.

5. Quarkus: Selamat bersenang-senang coding

Pengarang: Edson Yanaga
Panduan video untuk membuat proyek Quarkus pertama Anda, memungkinkan Anda memahami mengapa Quarkus memenangkan hati para pengembang.

6. Java dan container - bagaimana masa depan mereka bersama

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

7. Quarkus: Java Subatomik Supercepat

Pengarang: Dimitris Andreadis
Ikhtisar keunggulan Quarkus yang telah mendapat pengakuan dari pengembang: kesederhanaan, kecepatan sangat tinggi, perpustakaan dan standar terbaik.

8. Sistem roket Quarkus dan subatom

Pengarang: Clement Escoffier
Melalui integrasi dengan GraalVM, Quarkus memberikan pengalaman pengembangan ultra-cepat dan lingkungan runtime subatomik. Penulis membahas tentang sisi reaktif Quarkus dan cara menggunakannya untuk membangun aplikasi reaktif dan streaming.

9. Quarkus dan pengembangan aplikasi yang cepat di Eclipse MicroProfile

Pengarang: John Clingan
Dengan menggabungkan Eclipse MicroProfile dan Quarkus, pengembang dapat membuat aplikasi MicroProfile dalam container berfitur lengkap yang diluncurkan dalam waktu puluhan milidetik. Video ini menjelaskan secara rinci tentang cara membuat kode aplikasi MicroProfile dalam container untuk diterapkan pada platform Kubernetes.

10. Java, versi "Turbo".

Penulis: Marcus Biel
Penulis menunjukkan cara menggunakan Quarkus untuk membuat container Java super kecil dan super cepat yang memungkinkan terobosan nyata, terutama di lingkungan tanpa server.



Sumber: www.habr.com

Tambah komentar