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?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:
- Mengesahkan borang pendaftaran.
- Menyemak risiko alamat pengguna untuk memutuskan sama ada untuk memberikannya akaun bank.
- Membuka akaun bank.
BankController
akan 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. Gambar, 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...
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 kaedahriskCheck()
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 panggil semua perkhidmatan mikro yang digunakan secara berasingan, tanpa mengira saiz atau sempadan domain mereka.
- Mari kita fikirkan cara mengatur komunikasi antara perkhidmatan. Perkhidmatan mikro kami memerlukan cara untuk berkomunikasi antara satu sama lain.
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. Itu 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:- Selalunya, projek sedemikian sukar untuk dikekalkan/diubah/diperluaskan.
- Semua orang, daripada pembangun hingga pengurusan, mahukan pemudahan.
- Anda mempunyai (secara relatif) sempadan domain yang jelas, bermakna anda tahu dengan tepat perkara yang perlu dilakukan oleh perisian anda.
- 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. Untuk 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 BrownProjek dari awal berdasarkan seni bina perkhidmatan mikro
Untuk projek Java baharu, tiga item bernombor dari bahagian sebelumnya kelihatan sedikit berbeza:- Anda bermula dengan batu tulis yang bersih, jadi tidak ada "bagasi" untuk diselenggara.
- Pembangun ingin memastikan perkara mudah pada masa hadapan.
- Masalah: Anda mempunyai gambaran yang lebih kabur tentang sempadan domain: anda tidak tahu apa yang sepatutnya dilakukan oleh perisian anda (petunjuk: tangkas ;))
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):- Akan menyemak sama ada fail XML yang betul diterima.
- 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.
- Akan menggabungkan XML dengan beberapa data birokrasi lain.
- Akan memajukan fail XML kepada syarikat insurans untuk memulakan pembayaran.
- Dan ia akan menghantar keputusan kepada doktor, memberikannya mesej "berjaya" atau "sila hantar semula rakaman ini sebaik sahaja ia masuk akal."
- 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.
- 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.
- 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.
GO TO FULL VERSION