Cara berbagi DTO di seluruh layanan microser?

33

Skenario saya adalah sebagai berikut.

Saya merancang sistem yang dirancang untuk menerima data dari berbagai jenis sensor, dan mengkonversi dan kemudian bertahan untuk digunakan oleh berbagai layanan front-end dan analitik nanti.

Saya mencoba mendesain setiap layanan agar se independen mungkin, tetapi saya mengalami beberapa masalah. Tim telah memutuskan DTO yang ingin kami gunakan. Layanan yang menghadap ke luar (penerima data sensor) akan menerima data dengan caranya sendiri yang unik, kemudian mengonversinya menjadi objek JSON (DTO) dan mengirimkannya ke Pialang Pesan. Konsumen pesan akan tahu persis bagaimana membaca pesan data sensor.

Masalahnya adalah saya menggunakan DTO yang sama di beberapa layanan yang berbeda. Pembaruan harus diterapkan di beberapa lokasi. Jelas, kami telah merancang sedemikian rupa sehingga beberapa bidang tambahan atau hilang di DTO di sini dan tidak ada banyak masalah sampai layanan telah diperbarui, tetapi itu masih mengganggu saya dan membuat saya merasa seperti saya membuat kesalahan. Itu bisa dengan mudah berubah menjadi sakit kepala.

Apakah saya salah merancang sistem? Jika tidak, apa saja cara mengatasi hal ini, atau setidaknya untuk meredakan kekhawatiran saya?

nbaughman
sumber
DTO macam apa yang Anda bagikan, dan protokol apa yang Anda gunakan di antara layanan? Tidak apa-apa untuk berbagi, misalnya, protofile untuk gRPC atau avroskema untuk Kafka dan menghasilkan DTO di kedua layanan, tetapi saya tidak akan berbagi perpustakaan bersama antara dua proyek.
Vincent Savard
String JSON yang dikodekan dan AMQP. Saya lebih suka tidak menggunakan bahasa apa pun yang spesifik.
nbaughman

Jawaban:

38

Saranku? Jangan membagikan DTO ini di antara aplikasi di perpustakaan jenis apa pun. Atau setidaknya jangan lakukan ini sekarang.

Saya tahu, tampaknya sangat kontra-intuitif. Anda menggandakan kode, bukan? Tapi ini bukan aturan bisnis, jadi Anda bisa lebih fleksibel.

Layanan yang mengirim DTO harus kaku dalam kontrak pesannya, seperti API Istirahat. Layanan tidak dapat mengubah DTO dengan cara yang dapat merusak layanan lain yang sudah mengkonsumsi informasi dari DTO.

Ketika bidang baru ditambahkan lakukan DTO, Anda hanya memperbarui layanan lain yang mengkonsumsi DTO ini jika mereka membutuhkan bidang baru. Kalau tidak, lupakan saja. Menggunakan JSON sebagai tipe konten, Anda memiliki fleksibilitas untuk membuat dan mengirim atribut baru tanpa merusak kode layanan yang tidak memetakan bidang baru ini pada versi DTO yang sebenarnya.

Tetapi jika situasi ini benar-benar mengganggu Anda, Anda dapat mengikuti Aturan Tiga :

Ada dua "Aturan Tiga" yang digunakan kembali: (a) Tiga kali lebih sulit untuk membangun komponen yang dapat digunakan kembali seperti komponen sekali pakai, dan (b) komponen yang dapat digunakan kembali harus dicoba dalam tiga aplikasi yang berbeda sebelum akan cukup umum untuk menerima ke perpustakaan reuse.

Jadi, cobalah menunggu lebih lama sebelum membagikan DTO ini di antara layanan.

Dherik
sumber
1
Sangat dihargai. Ini benar-benar salah satu dari sedikit masalah utama yang saya hadapi. Tidak cukup untuk membuatku terjaga di malam hari, tapi cukup membuatku khawatir.
nbaughman
4
Duplikat DTO (dalam layanan yang berbeda dan sangat independen) tidak melanggar KERING. Itu dia.
Laiv
3
Agaknya maka tidak ada alasan untuk tidak menyalin kode sumber DTO langsung dari satu proyek ke proyek lain, sebagai operasi satu kali, meskipun kemudian setiap bagian yang tidak diperlukan dalam proyek baru mungkin harus dihapus.
bdsl
1
Bahkan seluruh layanan mungkin dihapus yang tidak menyebabkan masalah besar pada keseluruhan sistem. Idealnya.
Laiv
4
Untuk mengklarifikasi inti dari jawabannya, ketika mengembangkan layanan-layanan mikro, setiap layanan harus dikembangkan seolah-olah mereka tidak tahu tentang layanan lain, kecuali untuk kontrak aktual yang mungkin diperlukan.
Jonathan van de Veen
12

Ketika datang ke Microservices, siklus hidup pengembangan layanan juga harus independen. *

SLDC dan tim pengembang berbeda

dalam sistem MS nyata, mungkin ada beberapa tim yang terlibat dalam pengembangan ekosistem, yang masing-masing bertanggung jawab atas satu atau lebih layanan. Pada gilirannya, tim-tim ini mungkin berlokasi di kantor, kota, negara, rencana yang berbeda ... Mungkin, mereka bahkan tidak saling mengenal, apa yang membuat berbagi pengetahuan atau kode sangat sulit (jika mungkin). Tetapi ini bisa sangat nyaman karena kode bersama juga menyiratkan semacam alasan berbagi dan sesuatu yang penting untuk diingat adalah bahwa, apa pun yang masuk akal untuk tim tertentu, tidak harus membuatnya untuk tim lain. Misalnya, mengingat Pelanggan DTO , bisa berbeda tergantung pada layanan yang dimainkan, karena pelanggan ditafsirkan (atau dilihat) berbeda dari setiap layanan.

Kebutuhan berbeda, teknologi berbeda

SLDC yang terisolasi juga memungkinkan tim untuk memilih tumpukan yang paling sesuai dengan kebutuhan mereka. Memaksakan DTO yang diterapkan dalam teknologi tertentu membatasi kapasitas tim untuk memilih.

DTO bukanlah aturan bisnis atau kontrak layanan

Apa DTO sebenarnya? Objek polos tanpa tujuan lain selain memindahkan data dari satu sisi ke sisi lain. Tas getter dan setter. Bukan jenis "pengetahuan" yang layak digunakan kembali, secara keseluruhan karena tidak ada pengetahuan sama sekali. Volatilitas mereka juga membuat mereka kandidat yang buruk untuk digabungkan.

Bertentangan dengan apa yang Dherik telah menyatakan, itu harus mungkin untuk layanan untuk mengubah DTOs tanpa harus membuat layanan lain untuk perubahan pada waktu yang sama. Layanan harus menjadi pembaca yang toleran, penulis yang toleran, dan toleran yang gagal . Jika tidak, mereka menyebabkan sambungan sedemikian rupa sehingga membuat arsitektur layanan menjadi tidak masuk akal. Sekali lagi, dan bertentangan dengan jawaban Dherik, jika tiga layanan membutuhkan DTO yang persis sama, kemungkinan ada yang salah selama dekomposisi layanan.

Bisnis yang berbeda, interpretasi yang berbeda

Meskipun mungkin ada (dan akan ada) konsep lintas sektor di antara layanan, itu tidak berarti kita harus memaksakan model kanonik untuk memaksa semua layanan menafsirkannya dengan cara yang sama.

Studi kasus

Katakanlah perusahaan kami memiliki tiga departemen, Layanan Pelanggan , Penjualan dan Pengiriman . Katakanlah setiap rilis ini satu atau lebih layanan.

Layanan Pelanggan, karena bahasa domainnya , mengimplementasikan layanan di sekitar konsep pelanggan, di mana pelanggan adalah orang . Misalnya, pelanggan dimodelkan sebagai nama , nama belakang , usia , jenis kelamin , email , telepon , dll.

Sekarang katakanlah, Penjualan dan Pengiriman memodelkan layanan mereka sesuai dengan bahasa domain masing-masing juga. Dalam bahasa-bahasa ini, pelanggan konsep juga muncul tetapi dengan perbedaan yang halus. Bagi mereka, pelanggan bukanlah (harus) orang . Untuk Penjualan , pelanggan adalah nomor Dokumen sebuah Kartu Kredit dan alamat penagihan , untuk Pengiriman sebuah nama lengkap dan alamat pengiriman juga.

Jika kami memaksa Penjualan dan Pengiriman untuk mengadopsi model data kanonik dari Layanan Pelanggan , kami memaksa mereka untuk berurusan dengan data yang tidak perlu yang akhirnya dapat memperkenalkan kompleksitas yang tidak perlu jika mereka harus mempertahankan seluruh representasi dan menjaga data pelanggan tetap sinkron dengan layanan pelanggan. .

Tautan yang berhubungan


* Di sinilah letak kekuatan arsitektur ini

Laiv
sumber
Terima kasih! Studi kasus sebenarnya adalah apa yang membantu saya menentukan apakah akan membagikan DTO atau tidak. Sekarang saya yakin mengapa saya tidak ingin membagikannya.
Igor
8

Saya mencoba mendesain setiap layanan agar se independen mungkin

Anda harus menerbitkan acara . Peristiwa adalah jenis pesan tertentu yang mewakili fakta kuat tentang sesuatu yang telah terjadi pada titik waktu tertentu.

Setiap layanan harus memiliki tanggung jawab yang sangat jelas, dan harus memiliki tanggung jawab untuk mempublikasikan acara yang terkait dengan tanggung jawab itu.

Selain itu, Anda ingin acara Anda mewakili acara terkait bisnis, bukan acara teknis. Misalnya, lebih suka OrderCancelledacara OrderUpdateddengan status: "CANCELLED".

Dengan begitu, ketika layanan perlu bereaksi terhadap pesanan yang dibatalkan, itu hanya perlu mendengarkan jenis pesan tertentu, yang hanya membawa data yang relevan dengan acara itu. Misalnya, OrderCancelledmungkin hanya perlu order_id. Layanan apa pun yang perlu bereaksi terhadap hal ini telah menyimpan apa pun yang perlu diketahui tentang pesanan di penyimpanan datanya sendiri.

Tetapi jika layanan hanya memiliki OrderUpdatedacara untuk didengarkan, maka perlu menafsirkan aliran acara, dan sekarang tergantung pada pesanan pengiriman untuk menyimpulkan dengan benar ketika pesanan dibatalkan.

Dalam kasus Anda, namun, seperti Anda mempublikasikan data sensor, bisa masuk akal untuk memiliki layanan, mendengarkan acara dan mempublikasikan aliran baru dari "kegiatan bisnis", misalnya TemperatureThresholdExceeded, TemperatureStabilised.

Dan berhati-hatilah dalam membuat terlalu banyak layanan microser. Layanan Microsoft dapat menjadi cara yang bagus untuk merangkum kompleksitas, tetapi jika Anda tidak menemukan batasan layanan yang sesuai, kompleksitas Anda ada dalam integrasi layanan. Dan itu adalah mimpi buruk untuk dipertahankan.

Lebih baik memiliki layanan terlalu sedikit, terlalu besar, daripada terlalu banyak, terlalu kecil.

Pete
sumber
Saya pasti setuju. Data sensor datang langsung ke layanan microser yang mem-parsing pesan dan mengubahnya menjadi format yang disetujui seluruh organisasi sebelum menerbitkannya ke broker. Kami akan memiliki beberapa layanan yang membaca pesan dan bertahan ke database, dan layanan lainnya yang melakukan analisis pesan dan melakukan hal mereka sendiri dengan itu. Setiap layanan, pada dasarnya bisnis, tidak memiliki banyak yang harus dilakukan, sehingga mengarah ke (mudah-mudahan) layanan yang cukup sederhana.
nbaughman
2
@ Nickdb93 - Dalam kasus Anda, karena Anda mempublikasikan data sensor, masuk akal untuk memiliki layanan, mendengarkan acara, dan menerbitkan aliran baru "acara bisnis", misalnya TemperatureThresholdExceeded, TemperatureStabilised. (ditambahkan ke jawaban)
Pete