Saya telah membaca banyak tentang arsitektur microservice untuk aplikasi server, dan telah bertanya-tanya bagaimana penggunaan jaringan internal bukanlah hambatan atau kelemahan yang signifikan dibandingkan dengan arsitektur monolith.
Demi ketepatan, berikut adalah interpretasi saya dari dua istilah:
Arsitektur Monolith: Satu aplikasi dalam satu bahasa yang menangani semua fungsi, data, dll. Load balancer mendistribusikan permintaan dari pengguna akhir di beberapa mesin, masing-masing menjalankan satu instance dari aplikasi kami.
Arsitektur microservice: Banyak aplikasi (microservices) yang menangani sebagian kecil fungsi dan data. Setiap microservice memaparkan API umum yang diakses melalui jaringan (sebagai lawan komunikasi antar-proses atau memori bersama pada mesin yang sama). Panggilan API biasanya dilakukan di server untuk menghasilkan halaman, meskipun mungkin sebagian dari pekerjaan ini dilakukan oleh klien yang meminta layanan microser individual.
Untuk imajinasi naif saya, sepertinya arsitektur layanan microser menggunakan lalu lintas jaringan yang lambat sebagai lawan dari sumber daya yang lebih cepat pada mesin yang sama (memori dan disk). Bagaimana cara memastikan bahwa permintaan API melalui jaringan internal tidak akan memperlambat keseluruhan waktu respons?
sumber
Jawaban:
Jaringan internal sering menggunakan koneksi 1 Gbps, atau lebih cepat. Koneksi serat optik atau ikatan memungkinkan bandwidth yang jauh lebih tinggi antara server. Sekarang bayangkan ukuran rata-rata respons JSON dari API. Berapa banyak tanggapan semacam itu dapat ditransmisikan melalui koneksi 1 Gbps dalam satu detik?
Mari kita benar-benar menghitung. 1 Gbps adalah 131 072 KB per detik. Jika respons JSON rata-rata adalah 5 KB (yang cukup banyak!), Anda dapat mengirim 26 214 respons per detik melalui kabel hanya dengan satu pasang mesin . Tidak terlalu buruk, bukan?
Inilah sebabnya mengapa koneksi jaringan biasanya bukan hambatan.
Aspek lain dari layanan microser adalah Anda dapat mengukur dengan mudah. Bayangkan dua server, satu hosting API, satu lagi memakannya. Jika koneksi menjadi penghambat, tambahkan saja dua server lain dan Anda dapat menggandakan kinerjanya.
Inilah saat 2626 respons kami sebelumnya per detik menjadi terlalu kecil untuk skala aplikasi. Anda menambahkan sembilan pasangan lain, dan sekarang Anda dapat melayani 262 140 respons.
Tapi mari kita kembali ke pasangan server kita dan melakukan perbandingan.
Jika permintaan non-cache rata-rata ke database membutuhkan 10 ms., Anda dibatasi hingga 100 kueri per detik. 100 pertanyaan. 26 214 tanggapan. Mencapai kecepatan 26 214 respons per detik membutuhkan sejumlah besar caching dan optimisasi (jika respons tersebut benar-benar perlu melakukan sesuatu yang bermanfaat, seperti meng-query database; "Hello World" - style-response tidak memenuhi syarat).
Di komputer saya, sekarang, DOMContentLoaded untuk beranda Google terjadi 394 ms. setelah permintaan dikirim. Itu kurang dari 3 permintaan per detik. Untuk beranda Programmers.SE, itu terjadi 603 ms. setelah permintaan dikirim. Itu bahkan 2 permintaan per detik. Omong-omong, saya memiliki koneksi internet 100 Mbps dan komputer cepat: banyak pengguna akan menunggu lebih lama.
Jika hambatannya adalah kecepatan jaringan antara server, kedua situs tersebut dapat melakukan ribuan panggilan ke API yang berbeda saat melayani halaman.
Kedua kasus menunjukkan bahwa jaringan mungkin tidak akan menjadi hambatan Anda dalam teori (dalam praktek, Anda harus melakukan benchmark aktual dan profiling untuk menentukan lokasi yang tepat dari bottleneck dari Anda sistem tertentu host pada hardware tertentu). Waktu yang dihabiskan untuk melakukan pekerjaan yang sebenarnya (apakah itu query SQL, kompresi, apa pun) dan mengirim hasilnya ke pengguna akhir jauh lebih penting.
Pikirkan tentang basis data
Biasanya, basis data dihosting secara terpisah dari aplikasi web yang menggunakannya. Hal ini dapat menimbulkan kekhawatiran: bagaimana dengan kecepatan koneksi antara server hosting aplikasi dan server hosting database?
Tampaknya ada kasus di mana memang, kecepatan koneksi menjadi bermasalah, yaitu ketika Anda menyimpan sejumlah besar data yang tidak perlu diproses oleh database itu sendiri dan harus tersedia sekarang (itu adalah file biner besar). Tetapi situasi seperti itu jarang terjadi: dalam kebanyakan kasus, kecepatan transfer tidak sebesar itu dibandingkan dengan kecepatan pemrosesan permintaan itu sendiri.
Ketika kecepatan transfer sebenarnya penting adalah ketika sebuah perusahaan menjadi tuan rumah set data besar pada NAS, dan NAS diakses oleh banyak klien pada saat yang sama. Di sinilah SAN bisa menjadi solusi. Ini dikatakan, ini bukan satu-satunya solusi. Kabel Cat 6 dapat mendukung kecepatan hingga 10 Gbps; ikatan juga dapat digunakan untuk meningkatkan kecepatan tanpa mengubah kabel atau adapter jaringan. Solusi lain ada, yang melibatkan replikasi data di beberapa NAS.
Lupakan kecepatan; pikirkan skalabilitas
Poin penting dari aplikasi web adalah untuk dapat mengukur. Meskipun kinerja aktual penting (karena tidak ada yang mau membayar untuk server yang lebih kuat), skalabilitas jauh lebih penting, karena skalabilitas memungkinkan Anda untuk melemparkan perangkat keras tambahan saat dibutuhkan.
Jika Anda memiliki aplikasi yang tidak terlalu cepat, Anda akan kehilangan uang karena Anda akan memerlukan server yang lebih kuat.
Jika Anda memiliki aplikasi cepat yang tidak bisa menskalakan, Anda akan kehilangan pelanggan karena Anda tidak akan bisa menanggapi permintaan yang meningkat.
Dengan cara yang sama, mesin virtual satu dekade lalu dianggap sebagai masalah kinerja yang sangat besar. Memang, hosting aplikasi di server vs hosting di mesin virtual memiliki dampak kinerja yang penting. Meskipun jaraknya jauh lebih kecil hari ini, masih ada.
Meskipun kehilangan kinerja ini, lingkungan virtual menjadi sangat populer karena fleksibilitas yang mereka berikan.
Seperti halnya kecepatan jaringan, Anda mungkin menemukan bahwa VM adalah hambatan yang sebenarnya dan mengingat skala Anda yang sebenarnya, Anda akan menghemat miliaran dolar dengan hosting aplikasi Anda secara langsung, tanpa VM. Tapi ini bukan yang terjadi pada 99,9% aplikasi: kemacetannya ada di tempat lain, dan kelemahan dari hilangnya beberapa mikrodetik karena VM mudah dikompensasi oleh manfaat abstraksi perangkat keras dan skalabilitas.
sumber
Saya pikir Anda terlalu banyak membaca bagian 'mikro'. Itu tidak berarti mengganti setiap kelas dengan layanan jaringan, tetapi komponen aplikasi monolitik menjadi komponen berukuran masuk akal, masing-masing berurusan dengan aspek program Anda. Layanan tidak akan berbicara satu sama lain, jadi paling buruk Anda telah membagi permintaan jaringan besar menjadi beberapa yang lebih kecil. Data yang dikembalikan tidak akan jauh berbeda dengan apa yang Anda terima (meskipun Anda mungkin mengembalikan lebih banyak data dan menggabungkannya di klien)
sumber
Dengan menyusun kode dan akses sumber daya Anda sehingga sistem yang dihasilkan dapat cukup fleksibel untuk dijalankan sebagai aplikasi monolitik atau aplikasi terdistribusi melalui konfigurasi. Jika Anda menghapus abstrak mekanisme komunikasi di balik beberapa antarmuka umum dan Anda membangun sistem Anda dengan mempertimbangkan konkurensi, Anda dapat dengan mudah mengoptimalkan semuanya setelah Anda membuat profil sistem Anda dan menemukan leher botol yang sebenarnya.
sumber
Saya ingin menambahkan perspektif yang berbeda, dari industri yang berbeda dengan asumsi yang sangat berbeda - simulasi distribusi (entitas-level). Secara konseptual, ini sangat mirip dengan video game FPS yang didistribusikan. Perbedaan utama: semua pemain berbagi keadaan: di mana naga itu sekarang; tidak ada panggilan basis data; semuanya disimpan dalam RAM untuk kecepatan dan latensi rendah, throughput kurang relevan (tapi saya kira Anda tidak bisa mengabaikannya juga).
Anda dapat menganggap setiap aplikasi yang berpartisipasi baik sebagai monolith (yang mewakili semua sisi pemain), atau sebagai layanan mikro (yang hanya mewakili satu pemain di tengah kerumunan).
Ada ketertarikan dari kolega saya untuk memecah satu aplikasi yang berpartisipasi itu sendiri, lebih jauh ke dalam layanan microser kecil yang mungkin dibagikan, misalnya kerusakan arbitrase atau perhitungan line-of-sight, hal-hal yang biasanya dimasukkan ke dalam simulasi.
Masalahnya adalah latensi pengiriman panggilan dan menunggu permintaan. Bandwidth tidak relevan dan berlimpah, seperti yang ditunjukkan orang lain. Tetapi jika perhitungan line-of-sight berjalan dari 1 microsec ke 100 microsec (katakanlah, karena antrian dalam microservice baru yang dibagikan di antara semua aplikasi pemain), itu adalah kerugian besar (mungkin perlu beberapa atau banyak perhitungan line-of-sight untuk setiap pembaruan, beberapa pembaruan / detik).
Pikirkan baik-baik tentang cara kerja layanan, kapan mereka dipanggil, dan data apa yang dipertukarkan. Aplikasi kami sudah tidak bertukar hanya info posisi, mereka bertukar info perhitungan mati - Saya di posisi x, menuju ke arah y dengan kecepatan q. Dan saya tidak perlu memperbarui info saya sampai asumsi-asumsi itu berubah. Banyak pembaruan yang lebih sedikit, dan latensi (walaupun masih merupakan masalah) muncul secara lebih jarang secara proporsional.
Jadi, alih-alih meminta layanan dengan butiran halus pada frekuensi yang lebih tinggi, coba turunkan frekuensinya dengan:
Sekarang ingatlah untuk memeriksa asumsi Anda tentang sistem Anda. Jika Anda lebih mementingkan throughput daripada latensi, atau tidak memiliki status berbagi, dll., Tentu saja, gunakan layanan microsoft di mana mereka masuk akal. Saya hanya mengatakan mungkin jangan menggunakannya di tempat yang tidak masuk akal.
sumber
Imajinasi naif Anda benar. Dan seringkali itu tidak masalah. Mesin modern cepat. Keuntungan utama dari arsitektur layanan mikro terlihat dalam pengembangan dan upaya pemeliharaan dan waktu.
Dan tentu saja tidak ada aturan yang mengatakan Anda tidak dapat menggunakan memori bersama atau bahkan secara fisik menggunakan beberapa layanan dalam satu yang dapat dieksekusi. Selama Anda mendesainnya, jangan bergantung pada itu.
sumber
Seperti yang banyak orang sebutkan, ini bukan tentang kemacetan jaringan. Ini lebih tentang kerapuhan jaringan. Jadi langkah pertama adalah menghindari komunikasi yang sinkron. Lebih mudah daripada kedengarannya. Yang Anda butuhkan adalah layanan dengan batas yang benar. Batas kanan menghasilkan layanan yang otonom, longgar, dan sangat kohesif. Layanan yang baik tidak memerlukan informasi dari layanan lain, sudah ada. Satu-satunya cara komunikasi yang baik adalah melalui acara. Layanan yang baik pada akhirnya juga konsisten, sehingga tidak ada transaksi yang didistribusikan.
Cara untuk mencapai kebaikan ini adalah mengidentifikasi kemampuan bisnis Anda terlebih dahulu. Kemampuan bisnis adalah tanggung jawab bisnis tertentu. Beberapa kontribusi untuk nilai bisnis secara keseluruhan. Jadi, inilah urutan langkah saya yang saya ambil ketika memikirkan batasan sistem:
Perlu diingat bahwa layanan bisnis mencakup orang, aplikasi, proses bisnis. Biasanya hanya sebagian yang direpresentasikan sebagai otoritas teknis.
Ini mungkin terdengar agak abstrak, jadi mungkin contoh identifikasi batas layanan akan menarik.
sumber
Hanya faktor lain untuk ditambahkan ke jawaban saat ini. Dengan layanan berbutir kasar . Anda ingin menghindari latensi dari semua panggilan jadi alih-alih membuat 10 panggilan, Anda membuat panggilan yang mendapatkan 10 data yang dibutuhkan dalam DTO.
Dan ingat bahwa layanan mikro tidak mikro seperti yang orang pikirkan.
sumber