JavaRush /Blog Java /Random-MS /Panduan untuk Perkhidmatan Mikro Java. Bahagian 1: Asas d...

Panduan untuk Perkhidmatan Mikro Java. Bahagian 1: Asas dan Seni Bina Microservices

Diterbitkan dalam kumpulan
Dalam panduan ini, anda akan mempelajari apa itu perkhidmatan mikro Java, cara mereka bentuk dan menciptanya. Ia juga merangkumi soalan tentang perpustakaan perkhidmatan mikro Java dan kemungkinan menggunakan perkhidmatan mikro. Terjemahan dan penyesuaian Java Microservices: A Practical Guide .

Java Microservices: Asas

Untuk memahami perkhidmatan mikro, anda mesti terlebih dahulu menentukan apa yang bukan perkhidmatan tersebut. Bukankah ia "monolit" - monolit Java: apakah itu dan apakah kelebihan atau kekurangannya? Panduan untuk Perkhidmatan Mikro Java.  Bahagian 1: Asas dan Seni Bina Perkhidmatan Mikro - 1

Apakah monolit Java?

Bayangkan anda bekerja untuk bank atau syarikat permulaan fintech. Anda memberi pengguna apl mudah alih yang boleh mereka gunakan untuk membuka akaun bank baharu. Dalam kod Java ini akan menyebabkan kehadiran kelas pengawal. Dipermudahkan, ia kelihatan seperti ini:
@Controller
class BankController {

    @PostMapping("/users/register")
    public void register(RegistrationForm form) {
        validate(form);
        riskCheck(form);
        openBankAccount(form);
        // etc..
    }
}
Anda memerlukan pengawal untuk:
  1. Mengesahkan borang pendaftaran.
  2. Menyemak risiko alamat pengguna untuk memutuskan sama ada untuk memberikannya akaun bank.
  3. Membuka akaun bank.
Kelas BankControllerakan dibungkus bersama-sama sumber anda yang lain ke dalam fail bank.jar atau bank.war untuk penggunaan - ini adalah monolit lama yang baik yang mengandungi semua kod yang diperlukan untuk menjalankan bank anda. Sebagai anggaran kasar, saiz awal fail .jar (atau .war) akan berjulat dari 1 hingga 100 MB. Kini anda hanya boleh menjalankan fail .jar pada pelayan anda... dan itu sahaja yang anda perlu lakukan untuk menggunakan aplikasi Java anda. Panduan untuk Perkhidmatan Mikro Java.  Bahagian 1: Asas dan Seni Bina Perkhidmatan Mikro - 2Gambar, segi empat tepat kiri atas: penempatan bank mono(lithic) java -jar bank.jar (cp .war/.ear ke dalam pelayan aplikasi). Segi empat tepat kanan: buka penyemak imbas.

Apakah masalah dengan monolit Java?

Tidak ada yang salah dengan monolit Java. Walau bagaimanapun, pengalaman telah menunjukkan bahawa jika dalam projek anda:
  • Terdapat banyak pengaturcara/pasukan/perunding yang bekerja...
  • ... atas monolit yang sama di bawah tekanan daripada pelanggan dengan keperluan yang sangat kabur...
  • dalam masa beberapa tahun...
... maka dalam kes ini fail bank.jar kecil anda bertukar menjadi gigabait kod yang besar sahaja, yang menakutkan untuk didekati, apatah lagi digunakan.

Bagaimana untuk mengurangkan saiz monolit Java?

Persoalan semula jadi timbul: bagaimana untuk membuat monolit lebih kecil? Pada masa ini bank.jar anda berjalan pada satu JVM, satu proses pada satu pelayan. Tidak lebih, tidak kurang. Dan sekarang ini pemikiran logik mungkin terlintas di fikiran: “Tetapi perkhidmatan pengesahan risiko boleh digunakan oleh jabatan lain dalam syarikat saya! Ia tidak berkaitan langsung dengan aplikasi perbankan monolitik saya! Mungkin ia perlu dipotong daripada monolit dan digunakan sebagai produk yang berasingan? Iaitu, secara teknikalnya, menjalankannya sebagai proses Java yang berasingan."

Apakah perkhidmatan mikro Java?

Dalam amalan, frasa ini bermakna bahawa kini panggilan kaedah riskCheck()tidak akan dibuat daripada BankController: kaedah atau komponen kacang ini dengan semua kelas tambahannya akan dialihkan ke projek Maven atau Gradlenya sendiri. Ia juga akan digunakan dan diletakkan di bawah kawalan versi secara bebas daripada monolit perbankan. Walau bagaimanapun, keseluruhan proses pengekstrakan ini tidak menjadikan modul RiskCheck baharu anda kepada perkhidmatan mikro semata-mata, kerana takrif perkhidmatan mikro terbuka kepada tafsiran. Ini membawa kepada perbincangan yang kerap dalam pasukan dan syarikat.
  • Adakah 5-7 kelas dalam projek mikro atau apa?
  • 100 atau 1000 kelas... masih mikro?
  • Adakah perkhidmatan mikro secara amnya berkaitan dengan bilangan kelas atau tidak?
Mari kita tinggalkan penaakulan teori, dan sebaliknya berpegang pada pertimbangan pragmatik dan lakukan ini:
  1. Mari kita panggil semua perkhidmatan mikro yang digunakan secara berasingan, tanpa mengira saiz atau sempadan domain mereka.
  2. Mari kita fikirkan cara mengatur komunikasi antara perkhidmatan. Perkhidmatan mikro kami memerlukan cara untuk berkomunikasi antara satu sama lain.
Jadi, untuk meringkaskan: sebelum ini anda mempunyai satu proses JVM, monolit yang kukuh untuk menjalankan bank. Kini anda mempunyai proses JVM monolit perbankan dan perkhidmatan mikro RiskCheck berasingan yang berjalan dalam proses JVMnya sendiri. Dan sekarang, untuk menyemak risiko, monolit anda mesti memanggil perkhidmatan mikro ini. Bagaimana untuk melakukan ini?

Bagaimana untuk mewujudkan komunikasi antara perkhidmatan mikro Java?

Secara umum dan secara umum, terdapat dua pilihan - komunikasi segerak dan tak segerak.

Komunikasi segerak: (HTTP)/REST

Biasanya, komunikasi disegerakkan antara perkhidmatan mikro berlaku melalui perkhidmatan seperti HTTP dan REST yang mengembalikan XML atau JSON. Sudah tentu, mungkin terdapat pilihan lain - ambil sekurang-kurangnya Google Protocol Buffers . Jika anda memerlukan respons segera, lebih baik menggunakan komunikasi REST. Dalam contoh kami, inilah yang perlu dilakukan, kerana pengesahan risiko diperlukan sebelum membuka akaun. Jika tiada pemeriksaan risiko, tiada akaun. Kami akan membincangkan alatan di bawah, dalam bahagian " Pustaka manakah yang terbaik untuk panggilan REST Java segerak ".

Pemesejan - Komunikasi Asynchronous

Komunikasi perkhidmatan mikro tak segerak biasanya dicapai dengan bertukar-tukar mesej dengan pelaksanaan JMS dan/atau menggunakan protokol seperti AMQP . Kami menulis "biasanya" di sini atas sebab: katakan bilangan penyepaduan e-mel/SMTP tidak boleh dipandang remeh. Gunakannya apabila anda tidak memerlukan respons segera. Sebagai contoh, pengguna mengklik butang "beli sekarang", dan anda pula ingin menjana invois. Proses ini sememangnya tidak sepatutnya berlaku dalam kitaran permintaan-tindak balas pembelian pengguna. Di bawah kami akan menerangkan alat yang terbaik untuk pemesejan Java tak segerak .

Contoh: REST API panggilan dalam Java

Katakan kita memilih komunikasi perkhidmatan mikro segerak. Dalam kes ini, kod Java kami (yang kami bentangkan di atas) pada tahap rendah akan kelihatan seperti ini. (dengan tahap rendah di sini kami maksudkan fakta bahawa untuk komunikasi mikroperkhidmatan, perpustakaan pelanggan biasanya dibuat yang mengabstrakkan anda daripada panggilan HTTP sebenar).
@Controller
class BankController {

    @Autowired
    private HttpClient httpClient;

    @PostMapping("/users/register")
    public void register(RegistrationForm form) {
        validate(form);
        httpClient.send(riskRequest, responseHandler());
        setupAccount(form);
        // etc..
    }
}
Berdasarkan kod tersebut, menjadi jelas bahawa kami kini perlu menggunakan dua perkhidmatan Java (mikro), Bank dan RiskCheck. Akibatnya, kami akan menjalankan dua proses JVM. Panduan untuk Perkhidmatan Mikro Java.  Bahagian 1: Asas dan Seni Bina Perkhidmatan Mikro - 3Itu sahaja yang anda perlukan untuk membangunkan projek perkhidmatan mikro Java: hanya bina dan gunakan bahagian yang lebih kecil (fail .jar atau .war) dan bukannya satu yang monolitik. Jawapan kepada soalan masih tidak jelas: bagaimana kita harus memotong monolit menjadi perkhidmatan mikro? Seberapa kecil kepingan ini, bagaimana untuk menentukan saiz yang betul? Jom semak.

Java Microservices Architecture

Dalam amalan, syarikat membangunkan projek perkhidmatan mikro dengan cara yang berbeza. Pendekatan bergantung pada sama ada anda cuba mengubah monolit sedia ada kepada projek perkhidmatan mikro atau memulakan projek dari awal.

Daripada monolit kepada perkhidmatan mikro

Salah satu idea yang paling logik ialah mengekstrak perkhidmatan mikro daripada monolit sedia ada. Ambil perhatian bahawa awalan "mikro" di sini sebenarnya tidak bermakna bahawa perkhidmatan yang diekstrak akan benar-benar kecil; ini tidak semestinya berlaku. Mari kita lihat latar belakang teori.

Idea: pecahkan monolit kepada perkhidmatan mikro

Pendekatan perkhidmatan mikro boleh digunakan pada projek warisan. Dan itulah sebabnya:
  1. Selalunya, projek sedemikian sukar untuk dikekalkan/diubah/diperluaskan.
  2. Semua orang, daripada pembangun hingga pengurusan, mahukan pemudahan.
  3. Anda mempunyai (secara relatif) sempadan domain yang jelas, bermakna anda tahu dengan tepat perkara yang perlu dilakukan oleh perisian anda.
Kembali kepada contoh kami, ini bermakna anda boleh melihat monolit perbankan Java anda dan cuba memecahkannya merentasi sempadan domain.
  • Jadi, adalah munasabah untuk memisahkan pemprosesan data pengguna (seperti nama, alamat, nombor telefon) ke dalam "Pengurusan Akaun" perkhidmatan mikro yang berasingan.
  • Atau "Modul Pemeriksa Risiko" yang disebut di atas yang menyemak tahap risiko pengguna dan boleh digunakan oleh banyak projek lain atau malah jabatan syarikat.
  • Atau modul invois yang menghantar invois dalam format PDF atau melalui mel.

Pelaksanaan idea: biarkan orang lain melakukannya

Pendekatan yang diterangkan di atas kelihatan hebat pada kertas dan gambar rajah seperti UML. Walau bagaimanapun, semuanya tidak begitu mudah. Pelaksanaan praktikalnya memerlukan penyediaan teknikal yang serius: jurang antara pemahaman kita tentang perkara yang bagus untuk diekstrak daripada monolit dan proses pengekstrakan itu sendiri adalah sangat besar. Kebanyakan projek perusahaan mencapai tahap di mana pembangun takut, katakan, menaik taraf versi Hibernate yang berusia 7 tahun kepada yang lebih baharu. Perpustakaan akan dikemas kini bersama-sama dengannya, tetapi terdapat bahaya sebenar untuk memecahkan sesuatu. Jadi pembangun yang sama itu kini perlu menggali kod warisan purba dengan sempadan transaksi pangkalan data yang tidak jelas dan mengekstrak perkhidmatan mikro yang jelas? Lebih kerap daripada tidak, masalah ini sangat kompleks dan tidak boleh "diselesaikan" di papan putih atau dalam mesyuarat seni bina. Panduan untuk Perkhidmatan Mikro Java.  Bahagian 1: Asas dan Seni Bina Perkhidmatan Mikro - 4Untuk memetik pemaju Twitter @simonbrown: Saya akan mengatakan ini lagi dan lagi... jika orang tidak dapat membina monolit dengan betul, perkhidmatan mikro tidak akan membantu. Simon Brown

Projek dari awal berdasarkan seni bina perkhidmatan mikro

Untuk projek Java baharu, tiga item bernombor dari bahagian sebelumnya kelihatan sedikit berbeza:
  1. Anda bermula dengan batu tulis yang bersih, jadi tidak ada "bagasi" untuk diselenggara.
  2. Pembangun ingin memastikan perkara mudah pada masa hadapan.
  3. Masalah: Anda mempunyai gambaran yang lebih kabur tentang sempadan domain: anda tidak tahu apa yang sepatutnya dilakukan oleh perisian anda (petunjuk: tangkas ;))
Ini membawa kepada syarikat mencuba projek baharu dengan perkhidmatan mikro Java.

Seni bina perkhidmatan mikro teknikal

Perkara pertama nampaknya paling jelas untuk pembangun, tetapi ada juga mereka yang sangat tidak menggalakkannya. Hadi Hariri mengesyorkan pemfaktoran semula "Extract Microservice" dalam IntelliJ. Dan walaupun contoh berikut sangat dipermudahkan, pelaksanaan yang diperhatikan dalam projek sebenar, malangnya, tidak pergi terlalu jauh daripadanya. Sebelum perkhidmatan mikro
@Service
class UserService {

    public void register(User user) {
        String email = user.getEmail();
        String username =  email.substring(0, email.indexOf("@"));
        // ...
    }
}
Dengan subrentetan perkhidmatan mikro Java
@Service
class UserService {

    @Autowired
    private HttpClient client;

    public void register(User user) {
        String email = user.getEmail();
        //теперь вызываем substring microservice via http
        String username =  httpClient.send(substringRequest(email), responseHandler());
        // ...
    }
}
Jadi anda pada dasarnya membungkus panggilan kaedah Java dalam panggilan HTTP, tanpa sebab yang jelas untuk berbuat demikian. Satu sebab, bagaimanapun, adalah ini: kekurangan pengalaman dan cuba memaksa pendekatan perkhidmatan mikro Java. Cadangan: Jangan lakukan ini.

Seni bina perkhidmatan mikro berorientasikan aliran kerja

Pendekatan biasa seterusnya ialah membahagikan perkhidmatan mikro Java ke dalam modul berasaskan aliran kerja. Contoh kehidupan sebenar: Di Jerman, apabila anda pergi ke doktor (awam), dia mesti merekodkan lawatan anda dalam sistem CRM perubatannya. Untuk mendapatkan bayaran daripada insurans, dia akan menghantar data tentang rawatan anda (dan rawatan pesakit lain) kepada pengantara melalui XML. Broker akan melihat fail XML ini dan (dipermudahkan):
  1. Akan menyemak sama ada fail XML yang betul diterima.
  2. Ia akan memeriksa kebolehpercayaan prosedur: katakan, seorang kanak-kanak berusia satu tahun yang menerima tiga prosedur pembersihan gigi dalam satu hari daripada pakar sakit puan kelihatan agak mencurigakan.
  3. Akan menggabungkan XML dengan beberapa data birokrasi lain.
  4. Akan memajukan fail XML kepada syarikat insurans untuk memulakan pembayaran.
  5. Dan ia akan menghantar keputusan kepada doktor, memberikannya mesej "berjaya" atau "sila hantar semula rakaman ini sebaik sahaja ia masuk akal."
Catatan. Dalam contoh ini, komunikasi antara perkhidmatan mikro tidak memainkan peranan, tetapi boleh dilakukan secara tak segerak oleh broker mesej (cth. RabbitMQ), kerana doktor tidak menerima maklum balas segera. Panduan untuk Perkhidmatan Mikro Java.  Bahagian 1: Asas dan Seni Bina Perkhidmatan Mikro - 5Sekali lagi, ini kelihatan hebat di atas kertas, tetapi persoalan semula jadi timbul:
  • Adakah perlu menggunakan enam aplikasi untuk memproses satu fail XML?
  • Adakah perkhidmatan mikro ini benar-benar bebas antara satu sama lain? Bolehkah mereka digunakan secara bebas antara satu sama lain? Dengan versi dan skema API yang berbeza?
  • Apakah yang dilakukan oleh perkhidmatan mikro kredibiliti jika perkhidmatan mikro pengesahan tidak berfungsi? Adakah sistem masih berfungsi?
  • Adakah perkhidmatan mikro ini berkongsi pangkalan data yang sama (mereka pasti memerlukan beberapa data biasa dalam jadual DB), atau adakah mereka masing-masing mempunyai mereka sendiri?
  • … dan banyak lagi.
Menariknya, rajah di atas kelihatan lebih mudah kerana setiap perkhidmatan kini mempunyai tujuannya yang tepat dan jelas. Dulu ia kelihatan seperti monolit yang menakutkan ini: Panduan untuk Perkhidmatan Mikro Java.  Bahagian 1: Asas dan Seni Bina Perkhidmatan Mikro - 6Walaupun anda boleh berhujah tentang kesederhanaan gambar rajah ini, anda pastinya kini perlu menyelesaikan cabaran operasi tambahan ini.
  • Anda bukan sahaja perlu menggunakan satu aplikasi, tetapi sekurang-kurangnya enam.
  • Anda mungkin perlu menggunakan berbilang pangkalan data, bergantung pada sejauh mana anda ingin pergi ke seni bina perkhidmatan mikro.
  • Anda perlu memastikan bahawa setiap sistem dalam talian dan berfungsi dengan baik.
  • Anda perlu memastikan bahawa panggilan anda antara perkhidmatan mikro benar-benar berdaya tahan (lihat Bagaimana untuk menjadikan perkhidmatan mikro Java berdaya tahan?).
  • Dan semua perkara lain yang ditunjukkan oleh persediaan ini - daripada tetapan pembangunan tempatan hingga ujian penyepaduan.
Jadi cadangannya ialah:
  • Jika anda bukan Netflix (kemungkinan besar, anda bukan Netflix)...
  • Melainkan anda mempunyai kemahiran kerja yang sangat kuat di mana anda membuka persekitaran pembangunan dan ia memanggil monyet huru-hara yang membuang pangkalan data pengeluaran anda yang mudah dipulihkan dalam 5 saat.
  • atau anda berasa seperti @monzo dan sanggup mencuba 1500 perkhidmatan mikro hanya kerana anda boleh.
→ Jangan lakukan ini. Dan kini ia kurang hiperbolik. Cuba untuk memodelkan perkhidmatan mikro merentasi sempadan domain nampaknya agak munasabah. Tetapi ini tidak bermakna anda perlu mengambil satu aliran kerja dan membahagikannya kepada bahagian individu yang kecil (menerima XML, mengesahkan XML, XML ke hadapan). Oleh itu, apabila anda memulakan projek baharu dengan perkhidmatan mikro Java dan sempadan domain masih sangat kabur, cuba pastikan saiz perkhidmatan mikro anda pada tahap yang rendah. Anda sentiasa boleh menambah lebih banyak modul kemudian. Dan pastikan anda mempunyai DevOps lanjutan dalam pasukan/syarikat/bahagian untuk menyokong infrastruktur baharu anda.

Poliglot atau seni bina perkhidmatan mikro berorientasikan pasukan

Terdapat pendekatan ketiga, hampir libertarian, untuk membangunkan perkhidmatan mikro: membenarkan pasukan atau bahkan individu untuk melaksanakan cerita pengguna menggunakan sebarang bahasa atau perkhidmatan mikro (pemasar memanggil pendekatan ini "pengaturcaraan poliglot"). Oleh itu, perkhidmatan pengesahan XML yang diterangkan di atas boleh ditulis dalam Java, manakala perkhidmatan mikro pengesahan pada masa yang sama boleh ditulis dalam Haskell (untuk menjadikannya bunyi secara matematik). Untuk perkhidmatan mikro penghantaran insurans, anda boleh menggunakan Erlang (kerana ia benar-benar perlu skala;)). Perkara yang mungkin kelihatan menyeronokkan dari sudut pandangan pembangun (membangunkan sistem yang sempurna dengan bahasa sempurna anda dalam persekitaran terpencil) sebenarnya, bukanlah yang dikehendaki oleh organisasi: penhomogenan dan penyeragaman. Ini bermakna set bahasa, perpustakaan dan alatan yang agak standard supaya pembangun lain boleh terus menyokong perkhidmatan mikro Haskell anda pada masa hadapan apabila anda beralih ke padang rumput yang lebih hijau. Panduan untuk Perkhidmatan Mikro Java.  Bahagian 1: Asas dan Seni Bina Perkhidmatan Mikro - 8Sejarah menunjukkan bahawa standardisasi biasanya menjadi terlalu mendalam. Sebagai contoh, pemaju di syarikat Fortune 500 yang besar kadangkala tidak dibenarkan menggunakan Spring kerana ia "bukan sebahagian daripada pelan hala tuju teknologi syarikat." Walau bagaimanapun, peralihan lengkap kepada pendekatan polyglot adalah perkara yang hampir sama, sisi lain daripada syiling yang sama. Syor: Jika anda akan menggunakan pengaturcaraan polyglot, cuba kurangkan variasi dalam ekosistem bahasa pengaturcaraan yang sama. Jadi, lebih baik menggunakan Kotlin dan Java bersama-sama (kedua-dua bahasa adalah berdasarkan JVM dan 100% serasi antara satu sama lain), daripada Java dan, katakan, Haskell. Dalam bahagian seterusnya, anda akan belajar tentang menggunakan dan menguji perkhidmatan mikro Java.
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION