Menangani perubahan dalam arsitektur layanan-didorong mikro

9

Saya sedang melakukan proyek penelitian di mana saya meneliti opsi untuk menangani perubahan dalam arsitektur layanan-mikro yang didorong oleh peristiwa.

Jadi, katakanlah kita punya aplikasi di mana kita mendapat empat layanan berbeda. Setiap layanan ini memiliki database sendiri untuk menyimpan data lokal.

Dalam pengaturan ini, keempat layanan berkomunikasi satu sama lain menggunakan Bus Acara. Jadi ketika sesuatu terjadi dalam suatu layanan, ia menerbitkan suatu peristiwa. Semua layanan lain yang tertarik pada acara itu akan memprosesnya dengan cara mereka sendiri.

Dalam hal ini berbagai layanan dalam arsitektur perlu memiliki "kontrak" tentang konten acara ini (atribut dll.). Jadi layanan memiliki "dependensi longgar ditambah" untuk peristiwa ini

Pertanyaan saya adalah: Bagaimana kita bisa menangani perubahan dalam acara ini?

Jadi, katakanlah layanan A mendaftarkan pengguna baru dalam aplikasi. Jadi ia mengirimkan acara "UserRegistered". Layanan B mengambil peristiwa itu dan memprosesnya. Tetapi beberapa pengembang di tim layanan C memutuskan bahwa mereka juga memerlukan jenis kelamin pengguna terdaftar. Jadi acara tersebut diubah dan atribut gender ditambahkan ke acara "UserRegistered".

Bagaimana kami dapat memastikan bahwa Layanan B masih dapat mengambil peristiwa yang sama dengan atribut tambahan tanpa menggunakan kembali?

Dan adakah cara lain untuk mendekati masalah ini kemudian mengversi peristiwa ini?

CGeense
sumber
Apa format pesan Anda, atau apakah itu sesuatu yang dapat Anda desain? Beberapa format pesan memungkinkan untuk atribut opsional. Bergantung pada implementasi pembaca, Anda dapat menambahkan atribut opsional tanpa perlu memperbarui semua pembaca.
Thomas Owens
Saya bebas memilih format yang akan digunakan untuk pesan saya. Saya pikir menggunakan JSON adalah cara terbaik untuk pergi. Sangat penting bahwa berbagai layanan ini dibangun dalam bahasa yang berbeda. Karena itulah format umum seperti XML atau JSON diperlukan.
CGeense

Jawaban:

1

Acara bukan tentang apa yang berubah. Itu tentang ketika sesuatu berubah.

Saya dapat membuat sistem acara yang sepenuhnya dipisahkan dari konten yang berubah. Dengan begitu semua yang saya pelajari dari suatu peristiwa adalah bahwa suatu objek telah diperbarui. Jika saya bahkan peduli bahwa objek telah diperbarui saya akan memberitahu apa pun yang tahu bagaimana berbicara dengan objek itu untuk bertanya apa yang berubah.

Itu tidak menyelesaikan masalah mengkomunikasikan perubahan ini. Itu hanya menghentikannya dari menjadi bagian dari sistem acara.

Contoh salah satu cara untuk memecahkan masalah perbedaan versi data adalah dengan membuat pengamat membuat dan menyerahkan koleksi objek yang diamati. Objek yang diamati mengisi koleksi dengan data terbaru dan ketika kontrol mengembalikan Anda (pengamat) memiliki apa yang Anda butuhkan. Jika ada tambahan yang tidak Anda pedulikan, karena Anda tidak pernah mendengarnya, Anda mengabaikannya.

Banyak cara lain untuk menguliti kucing itu, tetapi itulah yang saya lakukan dalam kasus ini.

candied_orange
sumber
Bukankah ini akan secara dramatis meningkatkan lalu lintas antar layanan? Menggunakan contoh dalam pertanyaan, UserRegisteredacara, jika ada acara yang tidak mengandung informasi tentang pengguna, akan ada 1 pesan yang dipublikasikan ke bus dan kemudian {jumlah layanan yang tertarik} permintaan ke layanan pengguna atau pesan yang dipublikasikan ke bus. Kemudian, akan ada {jumlah layanan yang tertarik} pesan kembali dari berbagai ukuran. Meskipun saya berpikir bahwa ini mungkin desain yang lebih bersih di atas kertas, jika kinerjanya mengkhawatirkan, ia rusak dalam sistem non-sepele, terutama melalui jaringan.
Thomas Owens
@ThomasOwens Mengirim data dengan acara berarti jika saya memiliki N pengamat saya mengirim pesan N. Mengirim acara saja berarti saya mengirim pesan 3N hanya 1 yang memiliki paket data. Timbangan itu baik-baik saja bahkan melalui jaringan. Satu-satunya downside signifikan adalah tiga kali lipat lag Anda. Tidak mengatakan Anda tidak dapat menemukan solusi yang lebih optimal untuk situasi tertentu. Saya menunjukkan bahwa sistem acara dan versi data tidak harus digabungkan.
candied_orange
1
Seluruh ide dari bus acara ini adalah untuk memisahkan layanan yang berbeda. Dengan menggunakan sepotong middleware, kita dapat memastikan bahwa layanan ini tidak saling mengenal dan dapat hidup dan berkomunikasi tanpa mengetahui keberadaan satu sama lain. Jika kami menghapus status dari acara ini dan membiarkan layanan terhubung satu sama lain secara langsung, kami menggabungkan layanan ini. Dengan cara itu, kita tidak akan pernah dapat menggunakan kembali satu layanan tanpa harus memindahkan kembali yang lain
CGeense
1
Intinya di sini adalah bahwa sistem acara atau tidak Anda memerlukan data yang dapat diperluas. JSON atau XML melakukan itu dengan baik jika Anda tidak mengubah nama atau struktur yang telah dibuat sebelumnya. Saya sudah melakukan hal yang sama dengan koleksi. Sistem acara seharusnya tidak peduli dengan gender. Jika mengirim data, data itu harus diteruskan dan sesuatu di ujung lainnya akan peduli dengan jenis kelamin atau tidak.
candied_orange
1

Kerangka kerja seperti NServiceBus menangani ini dengan menggunakan versi acara dengan pengiriman pesan polimorfik.

Misalnya, versi 1 dari Layanan A dapat menerbitkan acara sebagai IUserRegistered_v1. Ketika Layanan A versi 1.1 perlu menyertakan bidang tambahan, ia mungkin mendeklarasikan antarmuka IUserRegistered_v1_1, yang akan mewarisi dari IUserRegistered_v1 serta mendeklarasikan beberapa bidang tambahan.

Saat Layanan A menerbitkan acara IUserRegistered_v1_1, NServiceBus akan mengirimkan pesan ke semua titik akhir yang menangani IUserRegistered_v1 atau IUserRegistered_v1_1.

pnschofield
sumber
0

Peningkatan bertahap

Perubahan sederhana pada model adalah ketika pendengar mendaftar sebagai pengamat, mereka memasukkan daftar atau struktur lain dari elemen data yang ingin mereka ketahui. Ini dapat berfungsi jika data yang dikembalikan dari layanan sederhana tetapi jika Anda memiliki cukup banyak data hierarkis, ini bisa sangat rumit untuk diimplementasikan.

Rock-solid

Jika Anda benar-benar ingin cara yang kuat untuk melakukan desain layanan ini sehingga menyimpan sejarah perubahan yang telah dibuat untuk data yang disimpannya. Pada dasarnya, Anda tidak pernah memperbarui catatan dalam database Anda, Anda menambahkan catatan baru di mana masing-masing mewakili perubahan. Setiap catatan baru ini dikaitkan dengan id peristiwa yang mengidentifikasi tindakan. Catatan genap disimpan dengan semua info yang relevan tentang perubahan (siapa, apa, kapan, dll.) Ini memiliki beberapa manfaat lain yang berada di luar cakupan jawaban ini tetapi dibahas dalam artikel ini tentang teorema CAP .

Ketika perubahan dibuat, Anda membuat catatan acara dan menambahkan semua data baru ke database Anda. Kemudian Anda mempublikasikan acara ke pendengar yang berisi (minimal) id acara. Pendengar kemudian dapat meminta data yang terkait dengan id itu dan mendapatkan versi data yang terkait dengannya. Setiap pendengar kemudian dapat memperoleh apa pun yang dibutuhkan tanpa menyatukan kebutuhan pendengar lain yang berbeda secara bersamaan. Saya akan menyarankan Anda menambahkan subset dari bidang data yang paling umum digunakan ke pesan acara sehingga pendengar dapat menyaring acara yang mereka tidak tertarik. Ini dapat mengurangi chattiness dari proses dan beberapa pendengar mungkin tidak perlu menelepon kembali sama sekali. Ini juga melindungi Anda dari masalah waktu. Jika Anda hanya menelepon kembali ke layanan dan mendapatkan data berdasarkan kunci, mungkin ada perubahan lain yang terjadi di antara mendapatkan acara dan mengambil data untuk itu. Ini mungkin tidak masalah bagi semua pendengar tetapi bisa menciptakan masalah besar jika Anda perlu tahu tentang semua perubahan. Peningkatan desain tambahan di atas kompatibel dengan pendekatan ini jika Anda benar-benar ingin mengubahnya menjadi 11.

Beberapa dari ini mungkin berlebihan untuk apa yang perlu Anda lakukan tetapi dalam pengalaman saya jika Anda tidak memiliki cara yang tepat untuk melihat bagaimana catatan berubah dari waktu ke waktu, Anda atau seseorang yang bekerja dengan data Anda pada akhirnya akan menginginkannya.

JimmyJames
sumber
-1

@CandiedOrange membuat poin yang valid dalam komentar untuk jawabannya sendiri mengenai format data yang dapat diperluas seperti xml.

Seharusnya tidak masalah selama Anda menambahkan data. Namun, sediakan standar yang masuk akal untuk acara yang lebih lama / bidang yang tidak wajib.

Anda hanya perlu memperbarui layanan yang peduli - dalam hal ini - Jender. Pengurai xml / json harus dapat mengabaikan data tambahan untuk layanan lain. Ini tergantung pada pilihan Anda untuk parser dan format data acara, tentu saja.

Saya tidak setuju dengan acara yang tidak memiliki data yang relevan. Untuk sumber acara, acara harus menentukan apa yang telah berubah. Saat menerima acara, layanan lain tidak harus mengambil data dari sumber acara.

Sander Weerdenburg
sumber
Maksud saya adalah bahwa ia perlu menangani semua jenis perubahan. Pikirkan layanan yang menyiarkan suatu acara. Dan peristiwa itu mengandung properti yang sudah usang dan harus dihapus. Bahkan jika layanan lain ini tidak menggunakan properti, itu akan menghancurkan mereka hanya karena mereka mengharapkannya. Jadi saya membaca artikel ini di martinfowler.com tentang kontrak yang digerakkan konsumen: martinfowler.com/articles/consumerDrivenContracts.html Saat menerapkan prinsip ini. Setiap penyedia (acara) tahu apa yang diharapkan darinya. dengan informasi itu dia dapat memvalidasi jika dia melanggar salah satu konsumen.
CGeense