Komunikasi berbasis pesan asinkron

Tip

Konten ini adalah kutipan dari eBook, .NET Microservices Architecture for Containerized .NET Applications, tersedia di .NET Docs atau sebagai PDF yang dapat diunduh gratis dan dapat dibaca secara offline.

.NET Microservices Architecture for Containerized .NET Applications eBook cover thumbnail.

Olahpesan asinkron dan komunikasi berbasis peristiwa sangat penting saat menyebarkan perubahan di beberapa layanan mikro dan model domain terkait. Seperti disebutkan sebelumnya dalam diskusi layanan mikro dan Konteks Terikat (BC), model (Pengguna, Pelanggan, Produk, Akun, dll.) dapat berarti hal yang berbeda untuk layanan mikro atau BC yang berbeda. Itu berarti bahwa ketika perubahan terjadi, Anda memerlukan beberapa cara untuk merekonsiliasi perubahan di berbagai model. Solusinya adalah konsistensi akhir dan komunikasi berbasis peristiwa berdasarkan olah pesan asinkron.

Saat menggunakan olah pesan, proses berkomunikasi dengan bertukar pesan secara asinkron. Klien membuat perintah atau permintaan ke layanan dengan mengiriminya pesan. Jika layanan perlu membalas, layanan akan mengirim pesan yang berbeda kembali ke klien. Karena ini adalah komunikasi berbasis pesan, klien mengasumsikan bahwa balasan tidak akan segera diterima, dan mungkin tidak ada respons sama sekali.

Pesan terdiri dari header (metadata seperti identifikasi atau informasi keamanan) dan isi. Pesan biasanya dikirim melalui protokol asinkron seperti AMQP.

Infrastruktur pilihan untuk jenis komunikasi ini di komunitas layanan mikro adalah broker pesan ringan, yang berbeda dari broker besar dan orkestrator yang digunakan di SOA. Dalam broker pesan ringan, infrastruktur biasanya "bodoh", bertindak hanya sebagai broker pesan, dengan implementasi sederhana seperti RabbitMQ atau bus layanan yang dapat diskalakan di cloud seperti Azure Bus Layanan. Dalam skenario ini, sebagian besar pemikiran "cerdas" masih berlangsung di titik akhir yang menghasilkan dan mengonsumsi pesan-yaitu, dalam layanan mikro.

Aturan lain yang harus Anda coba ikuti, sebanyak mungkin, adalah hanya menggunakan pesan asinkron antara layanan internal, dan untuk menggunakan komunikasi sinkron (seperti HTTP) hanya dari aplikasi klien ke layanan front-end (API Gateway ditambah tingkat layanan mikro pertama).

Ada dua jenis komunikasi olah pesan asinkron: komunikasi berbasis pesan penerima tunggal, dan komunikasi berbasis pesan beberapa penerima. Bagian berikut ini menyediakan detail tentang jenis komunikasi tersebut.

Komunikasi berbasis pesan penerima tunggal

Komunikasi asinkron berbasis pesan dengan satu penerima berarti ada komunikasi titik-ke-titik yang mengirimkan pesan tepat kepada salah satu konsumen yang membaca dari saluran, dan bahwa pesan diproses hanya sekali. Namun, ada situasi khusus. Misalnya, dalam sistem cloud yang mencoba memulihkan secara otomatis dari kegagalan, pesan yang sama dapat dikirim ulang beberapa kali. Karena kegagalan jaringan atau lainnya, klien harus dapat mencoba kembali mengirim pesan, dan server harus menerapkan operasi agar idempogen untuk memproses pesan tertentu hanya sekali.

Komunikasi berbasis pesan penerima tunggal sangat cocok untuk mengirim perintah asinkron dari satu layanan mikro ke layanan mikro lainnya seperti yang ditunjukkan pada Gambar 4-18 yang mengilustrasikan pendekatan ini.

Setelah Anda mulai mengirim komunikasi berbasis pesan (baik dengan perintah atau peristiwa), Anda harus menghindari pencampuran komunikasi berbasis pesan dengan komunikasi HTTP sinkron.

A single microservice receiving an asynchronous message

Gambar 4-18. Satu layanan mikro menerima pesan asinkron

Ketika perintah berasal dari aplikasi klien, perintah tersebut dapat diimplementasikan sebagai perintah sinkron HTTP. Gunakan perintah berbasis pesan saat Anda memerlukan skalabilitas yang lebih tinggi atau saat Anda sudah dalam proses bisnis berbasis pesan.

Komunikasi berbasis pesan multi-penerima

Sebagai pendekatan yang lebih fleksibel, Anda mungkin juga ingin menggunakan mekanisme publikasi/berlangganan sehingga komunikasi Anda dari pengirim akan tersedia untuk layanan mikro pelanggan tambahan atau ke aplikasi eksternal. Dengan demikian, ini membantu Anda untuk mengikuti prinsip terbuka/tertutup dalam layanan pengirim. Dengan begitu, pelanggan tambahan dapat ditambahkan di masa mendatang tanpa perlu memodifikasi layanan pengirim.

Saat Anda menggunakan komunikasi terbitkan/berlangganan, Anda mungkin menggunakan antarmuka bus peristiwa untuk menerbitkan peristiwa ke pelanggan mana pun.

Komunikasi berbasis peristiwa asinkron

Saat menggunakan komunikasi berbasis peristiwa asinkron, layanan mikro menerbitkan peristiwa integrasi ketika sesuatu terjadi dalam domainnya dan layanan mikro lain perlu menyadarinya, seperti perubahan harga dalam layanan mikro katalog produk. Layanan mikro tambahan berlangganan peristiwa sehingga mereka dapat menerimanya secara asinkron. Ketika itu terjadi, penerima mungkin memperbarui entitas domain mereka sendiri, yang dapat menyebabkan lebih banyak peristiwa integrasi diterbitkan. Sistem terbitkan/berlangganan ini dilakukan dengan menggunakan implementasi bus peristiwa. Bus peristiwa dapat dirancang sebagai abstraksi atau antarmuka, dengan API yang diperlukan untuk berlangganan atau berhenti berlangganan peristiwa dan untuk menerbitkan peristiwa. Bus peristiwa juga dapat memiliki satu atau beberapa implementasi berdasarkan broker antarproses dan olah pesan, seperti antrean olah pesan atau bus layanan yang mendukung komunikasi asinkron dan model terbitkan/berlangganan.

Jika sistem menggunakan konsistensi akhir yang didorong oleh peristiwa integrasi, disarankan agar pendekatan ini diperjelas kepada pengguna akhir. Sistem tidak boleh menggunakan pendekatan yang menimpulkan peristiwa integrasi, seperti SignalR atau sistem polling dari klien. Pengguna akhir dan pemilik bisnis harus secara eksplisit merangkul konsistensi akhir dalam sistem dan menyadari bahwa dalam banyak kasus bisnis tidak memiliki masalah dengan pendekatan ini, selama itu eksplisit. Pendekatan ini penting karena pengguna mungkin berharap untuk segera melihat beberapa hasil dan aspek ini mungkin tidak terjadi dengan konsistensi akhir.

Seperti disebutkan sebelumnya di bagian Tantangan dan solusi untuk manajemen data terdistribusi, Anda dapat menggunakan peristiwa integrasi untuk menerapkan tugas bisnis yang mencakup beberapa layanan mikro. Dengan demikian, Anda akan memiliki konsistensi akhir antara layanan tersebut. Transaksi yang akhirnya konsisten terdiri dari kumpulan tindakan terdistribusi. Pada setiap tindakan, layanan mikro terkait memperbarui entitas domain dan menerbitkan peristiwa integrasi lain yang meningkatkan tindakan berikutnya dalam tugas bisnis end-to-end yang sama.

Poin pentingnya adalah Anda mungkin ingin berkomunikasi dengan beberapa layanan mikro yang berlangganan ke peristiwa yang sama. Untuk melakukannya, Anda dapat menggunakan pesan terbitkan/berlangganan berdasarkan komunikasi berbasis peristiwa, seperti yang ditunjukkan pada Gambar 4-19. Mekanisme terbitkan/berlangganan ini tidak eksklusif untuk arsitektur layanan mikro. Ini mirip dengan cara Konteks Terikat di DDD harus berkomunikasi, atau dengan cara Anda menyebarkan pembaruan dari database tulis ke database baca dalam pola arsitektur Pemisahan Tanggung Jawab Perintah dan Kueri (CQRS). Tujuannya adalah untuk memiliki konsistensi akhir antara beberapa sumber data di seluruh sistem terdistribusi Anda.

Diagram showing asynchronous event-driven communications.

Gambar 4-19. Komunikasi pesan berbasis peristiwa asinkron

Dalam komunikasi berbasis peristiwa asinkron, satu layanan mikro menerbitkan peristiwa ke bus peristiwa dan banyak layanan mikro dapat berlangganan, untuk mendapatkan pemberitahuan dan bertindak atasnya. Implementasi Anda akan menentukan protokol apa yang akan digunakan untuk komunikasi berbasis pesan yang didorong peristiwa. AMQP dapat membantu mencapai komunikasi antrean yang andal.

Saat menggunakan bus peristiwa, Anda mungkin ingin menggunakan tingkat abstraksi (seperti antarmuka bus peristiwa) berdasarkan implementasi terkait di kelas dengan kode menggunakan API dari broker pesan seperti RabbitMQ atau bus layanan seperti Azure Service Bus dengan Topik. Atau, Anda mungkin ingin menggunakan bus layanan tingkat lebih tinggi seperti NServiceBus, MassTransit, atau Brighter untuk mengartikulasikan bus peristiwa Anda dan menerbitkan/berlangganan sistem.

Catatan tentang teknologi olah pesan untuk sistem produksi

Teknologi olah pesan yang tersedia untuk mengimplementasikan bus peristiwa abstrak Anda berada pada tingkat yang berbeda. Misalnya, produk seperti RabbitMQ (transportasi broker olahpesan) dan Azure Bus Layanan duduk di tingkat yang lebih rendah daripada produk lain seperti NServiceBus, MassTransit, atau Brighter, yang dapat bekerja di atas RabbitMQ dan Azure Bus Layanan. Pilihan Anda tergantung pada berapa banyak fitur kaya di tingkat aplikasi dan skalabilitas out-of-the-box yang Anda butuhkan untuk aplikasi Anda. Untuk menerapkan hanya bus peristiwa bukti konsep untuk lingkungan pengembangan Anda, seperti yang dilakukan dalam sampel eShopOnContainers, implementasi sederhana di atas RabbitMQ yang berjalan pada kontainer Docker mungkin cukup.

Namun, untuk sistem misi penting dan produksi yang membutuhkan skalabilitas hiper, Anda mungkin ingin mengevaluasi Azure Service Bus. Untuk abstraksi dan fitur tingkat tinggi yang membuat pengembangan aplikasi terdistribusi lebih mudah, kami sarankan Anda mengevaluasi bus layanan komersial dan sumber terbuka lainnya, seperti NServiceBus, MassTransit, dan Brighter. Tentu saja, Anda dapat membangun fitur bus layanan Anda sendiri di atas teknologi tingkat bawah seperti RabbitMQ dan Docker. Tetapi pekerjaan itu mungkin terlalu mahal untuk aplikasi perusahaan kustom.

Menerbitkan ke bus kejadian dengan tangguh

Tantangan saat menerapkan arsitektur berbasis peristiwa di beberapa layanan mikro adalah cara memperbarui status secara atomik dalam layanan mikro asli sambil dengan tangguh menerbitkan peristiwa integrasi terkait ke dalam bus peristiwa, yang entah bagaimana, berdasarkan transaksi. Berikut ini adalah beberapa cara untuk mencapai fungsionalitas ini, meskipun mungkin ada pendekatan tambahan juga.

  • Menggunakan antrean transaksional (berbasis DTC) seperti MSMQ. (Namun, ini adalah pendekatan lama.)

  • Menggunakan penggalian log transaksi.

  • Menggunakan pola Sumber Peristiwa lengkap.

  • Menggunakan pola Kotak Keluar: tabel database transaksional sebagai antrean pesan yang akan menjadi dasar untuk komponen pembuat peristiwa yang akan membuat peristiwa dan menerbitkannya.

Untuk deskripsi yang lebih lengkap tentang tantangan di ruang ini, termasuk bagaimana pesan dengan data yang berpotensi salah akhirnya dapat diterbitkan, lihat Platform data untuk beban kerja misi penting di Azure: Setiap pesan harus diproses.

Topik tambahan yang perlu dipertimbangkan saat menggunakan komunikasi asinkron adalah idempotensi pesan dan deduplikasi pesan. Topik-topik ini dibahas dalam bagian Menerapkan komunikasi berbasis peristiwa antara layanan mikro (peristiwa integrasi) nanti dalam panduan ini.

Sumber daya tambahan