Hari ini kami menyampaikan kepada Anda materi kecil tentang layanan mikro dan arsitektur terdistribusi. Secara khusus, ini menyentuh gagasan Martin Fowler bahwa sistem baru harus dimulai dengan monolit, dan bahkan dalam arsitektur layanan mikro yang dikembangkan, disarankan untuk meninggalkan inti monolitik yang besar.
Selamat membaca!
Hari ini, semua orang berpikir dan menulis tentang layanan mikro, dan saya tidak terkecuali. Berdasarkan prinsip dasar layanan mikro dan konteks aslinya, jelaslah bahwa layanan mikro adalah sistem terdistribusi.
Apa itu transaksi terdistribusi?
Transaksi yang menjangkau beberapa sistem fisik atau komputer di jaringan disebut sebagai transaksi terdistribusi. Dalam dunia layanan mikro, transaksi dibagi menjadi beberapa layanan yang dipanggil secara berurutan untuk menyelesaikan seluruh transaksi.
Berikut adalah sistem toko online monolitik yang menggunakan transaksi:
Gambar. 1: Transaksi di Monolith
Jika dalam sistem di atas, pengguna mengirimkan permintaan pesanan (Checkout) ke platform, kemudian platform membuat transaksi lokal di database, dan transaksi ini mencakup banyak tabel database untuk memproses (Proses) pesanan dan cadangan(Cadangan) barang dari gudang. Jika salah satu langkah ini gagal, maka transaksi dapat dibatalkan , yang berarti penolakan pesanan itu sendiri dan barang yang dipesan. Serangkaian prinsip ini disebut ACID (Atomicity, Consistency, Isolation, Durability) dan dijamin di tingkat sistem database.
Berikut adalah dekomposisi sistem toko online yang dibangun dari layanan mikro:
Gambar 2: Transaksi dalam layanan mikro
Setelah mendekomposisi sistem ini, kami membuat layanan mikro
OrderMicroservice
danInventoryMicroservice
dengan database terpisah. Ketika permintaan untuk pesanan (Checkout) datang dari pengguna, kedua layanan mikro ini dipanggil, dan masing-masing membuat perubahan pada database-nya. Karena transaksi sekarang disebarkan ke beberapa database di beberapa sistem, itu dianggap terdistribusi .
Apa masalah saat melakukan transaksi terdistribusi di layanan mikro?
Dengan diperkenalkannya arsitektur layanan mikro, database kehilangan sifat ACID-nya. Karena kemungkinan proliferasi transaksi antara banyak layanan mikro dan oleh karena itu database, masalah utama berikut harus ditangani:
Bagaimana cara menjaga atomisitas transaksi?
Atomicity berarti bahwa dalam transaksi apa pun, semua langkah dapat diselesaikan, atau tidak sama sekali. Jika contoh di atas gagal menyelesaikan operasi 'item pesanan' dalam metode
InventoryMicroservice
, lalu bagaimana cara mengembalikan perubahan dalam 'pemrosesan pesanan' yang diterapkan OrderMicroservice
?
Bagaimana cara menangani permintaan persaingan?
Misalkan sebuah objek dari salah satu layanan mikro memasuki database untuk penyimpanan jangka panjang, dan pada saat yang sama permintaan lain membaca objek yang sama. Data apa yang harus dikembalikan layanan - lama atau baru? Dalam contoh di atas, jika
OrderMicroservice
sudah menyelesaikan pekerjaan dan InventoryMicroservice
sedang dalam proses pembaruan, apakah Anda perlu menyertakan pesanan saat ini dalam jumlah permintaan pesanan yang dibuat oleh pengguna?
Sistem modern dirancang dengan potensi kegagalan dalam pikiran, dan salah satu masalah utama dalam pemrosesan transaksi terdistribusi diartikulasikan dengan baik oleh Pat Helland.
Sebagai aturan, pengembang tidak membuat aplikasi berskala besar yang akan melibatkan pekerjaan dengan transaksi terdistribusi.
Solusi yang memungkinkan
Kedua masalah di atas sangat kritis dalam rangka merancang dan membangun aplikasi berbasis layanan mikro. Untuk mengatasinya, dua pendekatan berikut digunakan:
- Fiksasi dua fase
- Konsistensi dan Kompensasi Utama / SAGA
1. Fiksasi dua fase
Sesuai namanya, metode pemrosesan transaksi ini melibatkan dua tahap: fase persiapan dan fase komit. Peran penting dalam hal ini dimainkan oleh koordinator transaksi, yang mengatur siklus hidup transaksi.
Bagaimana itu bekerja
Pada tahap persiapan, semua layanan mikro yang berpartisipasi dalam pekerjaan bersiap untuk berkomitmen dan memberi tahu koordinator bahwa mereka siap untuk menyelesaikan transaksi. Kemudian, di langkah berikutnya, apakah komit terjadi, atau koordinator transaksi menginstruksikan semua layanan mikro untuk melakukan rollback.
Pertimbangkan lagi sistem toko online sebagai contoh:
Gambar 3: Komit dua-fase yang berhasil dalam sistem layanan mikro
Dalam contoh di atas (Gambar 3), ketika pengguna mengirimkan permintaan pesanan, koordinator
TransactionCoordinator
pertama-tama memulai transaksi global dengan informasi konteks lengkap. Pertama, ia mengirimkan perintah persiapkan ke layanan mikro OrderMicroservice
untuk membuat pesanan. Kemudian mengirimkan perintah persiapkan keInventoryMicroservice
untuk memesan barang. Saat kedua layanan siap untuk membuat perubahan, mereka memblokir objek dari perubahan lebih lanjut dan memberi tahu tentang hal itu TransactionCoordinator
. Setelah TransactionCoordinator
mengonfirmasi bahwa semua layanan mikro siap untuk menerapkan perubahannya, layanan mikro ini akan memerintahkan untuk menyimpannya dengan meminta komit transaksi. Pada titik ini, semua objek akan dibuka kuncinya.
Gambar 4: Komitmen dua fase yang gagal saat bekerja dengan layanan mikro
Dalam skenario kegagalan (Gambar 4) - jika suatu saat satu layanan mikro tidak memiliki waktu untuk mempersiapkan,
TransactionCoordinator
batalkan transaksi dan mulai proses rollback. Pada diagram, OrderMicroservice
untuk beberapa alasan, saya tidak dapat membuat pesanan, tetapi InventoryMicroservice
menjawab bahwa saya siap untuk membuat pesanan. Koordinator TransactionCoordinator
akan meminta pembatalan padaInventoryMicroservice
, setelah itu layanan akan mengembalikan semua perubahan yang dibuat dan membuka kunci objek database.
Manfaat
- Pendekatan ini menjamin atomicity transaksi. Transaksi akan selesai baik saat kedua layanan mikro berhasil, atau saat layanan mikro tidak membuat perubahan apa pun.
- Kedua, pendekatan ini memungkinkan Anda memisahkan pembacaan dari tulisan, karena perubahan pada objek tidak terlihat sampai koordinator transaksi melakukan perubahan ini.
- Pendekatan ini adalah panggilan sinkron di mana klien akan diberi tahu tentang keberhasilan atau kegagalan.
kerugian
- Tidak ada yang sempurna; komitmen dua fase cukup lambat dibandingkan dengan operasi layanan mikro tunggal. Mereka sangat bergantung pada koordinator. transaksi, yang secara signifikan dapat memperlambat sistem selama periode beban tinggi.
- Kelemahan utama lainnya adalah penguncian baris database. Penguncian dapat menjadi penghambat kinerja, dan kebuntuan dapat terjadi , di mana dua transaksi saling mengunci dengan erat.
2. Konsistensi dan Kompensasi Utama / SAGA
Salah satu definisi terbaik tentang konsistensi pada akhirnya diberikan di microservices.io: setiap layanan memublikasikan acara setiap kali datanya diperbarui. Layanan lain berlangganan acara. Ketika suatu peristiwa diterima, layanan memperbarui datanya .
Dengan pendekatan ini, transaksi terdistribusi dijalankan sebagai kumpulan transaksi lokal asinkron di layanan mikro yang sesuai. Layanan mikro bertukar informasi melalui bus acara.
Bagaimana itu bekerja
Sekali lagi, mari kita ambil contoh sistem yang berjalan di toko online:
Gambar 5: Konsistensi Utama / SAGA, Sukses
Dalam contoh di atas (Gambar 5), pelanggan membutuhkan sistem untuk memproses pesanan. Permintaan ini
Choreographer
memunculkan acara Buat Pesanan, yang memulai transaksi. Microservice OrderMicroservice
mendengarkan acara ini dan membuat pesanan - jika operasi ini berhasil, maka akan memunculkan acara Pesanan Dibuat. Koordinator Choreographer
mendengarkan acara ini dan melanjutkan ke item pesanan, meningkatkan acara Item Cadangan. Layanan mikroInventoryMicroservice
mendengarkan acara ini dan memesan barang; Jika event ini berhasil, maka event Item Reserved akan muncul. Dalam contoh ini, ini berarti transaksi telah berakhir.
Semua komunikasi berbasis acara antara layanan mikro terjadi melalui bus acara, dan sistem lain bertanggung jawab atas pengorganisasiannya (koreografi) - begitulah cara masalah diselesaikan dengan kompleksitas yang tidak perlu.
Gambar 6: Konsistensi Tertinggi / SAGA, Hasil yang Gagal
Jika, karena alasan tertentu,
InventoryMicroservice
item tidak dipesan (Gambar 6), ini memunculkan acara Gagal untuk Mencadangkan Item. Koordinator Choreographer
mendengarkan acara ini dan memulai transaksi penyeimbangan, meningkatkan acara Hapus Pesanan. Layanan mikroOrderMicroservice
mendengarkan acara ini dan menghapus pesanan yang dibuat sebelumnya.
Manfaat
Keuntungan utama dari pendekatan ini adalah bahwa setiap layanan mikro hanya berfokus pada transaksi atomnya sendiri. Layanan mikro tidak diblokir jika layanan lain membutuhkan waktu yang relatif lama untuk dijalankan. Ini juga berarti Anda tidak perlu mengunci database juga. Dengan pendekatan ini, dimungkinkan untuk memastikan skalabilitas yang baik dari sistem saat bekerja di bawah beban tinggi, karena solusi yang diusulkan adalah asinkron dan berdasarkan pada bekerja dengan kejadian.
kerugian
Kerugian utama dari pendekatan ini adalah tidak menyediakan isolasi baca. Jadi, dalam contoh di atas, pelanggan akan melihat bahwa pesanan telah dibuat, tetapi setelah beberapa saat, pesanan akan dihapus selama transaksi offset. Selain itu, dengan bertambahnya jumlah layanan mikro, semakin sulit untuk men-debug dan memeliharanya.
Kesimpulan
Alternatif pertama untuk pendekatan yang diusulkan adalah meninggalkan transaksi terdistribusi sama sekali. Jika Anda membuat aplikasi baru, mulailah dengan arsitektur monolitik, seperti yang dijelaskan di MonolithFirst oleh Martin Fowler. Saya akan mengutip dia.
, , . , , . —Jika data perlu diperbarui di dua tempat sekaligus sebagai hasil dari satu peristiwa, maka pendekatan konsistensi / SAGA pada akhirnya lebih disukai daripada pendekatan dua fase saat memproses transaksi terdistribusi. Alasan utamanya adalah bahwa pendekatan dua fase dalam lingkungan terdistribusi tidak berskala. Menggunakan konsistensi juga pada akhirnya menimbulkan serangkaian masalahnya sendiri, seperti cara memperbarui database dan mengaktifkan peristiwa secara atomik. Pindah ke filosofi pengembangan seperti itu, perlu untuk mengubah persepsinya baik dari sudut pandang pengembang maupun dari sudut pandang penguji.