Saya merancang sistem yang menggunakan Pengadaan Acara, CQRS, dan layanan mikro. Saya mengerti bahwa ini bukan pola yang tidak biasa. Fitur utama dari layanan ini adalah kemampuan untuk merehidrasi / memulihkan dari sistem catatan. Layanan Microsoft akan menghasilkan perintah dan permintaan pada MQ (Kafka). Layanan microser lainnya akan merespons (acara). Perintah dan pertanyaan akan tetap ada pada S3 untuk tujuan audit dan pemulihan.
Proses pemikiran saat ini adalah bahwa, untuk tujuan memulihkan sistem, kita dapat mengekstrak log peristiwa dari S3 dan hanya memasukkannya kembali ke Kafka.
Namun, ini gagal untuk mengakui perubahan produsen dan konsumen dari waktu ke waktu. Versi pada tingkat perintah / kueri tampaknya menuju penyelesaian masalah tetapi saya tidak bisa memahami konsumen versi sehingga saya bisa menegakkan bahwa ketika perintah, selama pemulihan, diterima dan diproses, itu sama persis kode [versi] yang melakukan pemrosesan karena ini adalah pertama kalinya perintah diterima.
Apakah ada pola yang bisa saya gunakan untuk menyelesaikan ini? Adakah yang mengetahui sistem lain yang mengiklankan fitur ini?
EDIT: Menambahkan contoh.
'Pembeli' mengirim 'pertanyaan' ke 'penjual' di situs lelang saya. Alurnya terlihat sebagai berikut:
UI -> Web App: POST /question {:text text :to seller-id :from user-id}
Web App -> MQ: SEND {:command send-question :args [text seller-id user-id]}
MQ -< Audit: <command + args appended to log in S3>
MQ -< Questions service: - Record question in DB
- Email seller 'You have a question'
Sekarang, sebagai hasil dari persyaratan bisnis baru, saya menyesuaikan konsumen 'Layanan pertanyaan', untuk bertahan dalam hitungan semua pertanyaan yang belum dibaca. Skema DB diubah. Kami belum memiliki gagasan apakah pertanyaan dibacakan oleh penjual, sampai sekarang. Baris terakhir menjadi:
MQ -< Questions service: - Record question in DB
- Email seller 'You have a question'
- Increment 'unread questions count'
Dua perintah adalah masalah, satu sebelum perubahan, satu setelah perubahan. 'Jumlah pertanyaan yang belum dibaca' sama dengan 1.
Sistem macet. Kami memulihkan dengan memutar ulang perintah melalui kode baru . Pada akhir pemulihan, 'jumlah pertanyaan yang belum dibaca' kami sama dengan 2. Meskipun, dalam contoh yang dibuat-buat ini, hasilnya bukan bencana, keadaan yang telah dipulihkan bukan seperti sebelumnya.
sumber
Jawaban:
Pertama, penting untuk memahami dan dapat memanfaatkan perbedaan antara Perintah dan Acara.
Seperti yang ditunjukkan oleh pertanyaan ini dengan singkat, Perintah adalah hal-hal yang kita inginkan terjadi, dan Peristiwa adalah hal-hal yang telah terjadi. Perintah tidak selalu menghasilkan peristiwa penting dalam sistem, tetapi biasanya terjadi. Sebagai contoh, sebuah
send message
perintah dapat ditolak, dalam hal ini tidak ada peristiwa yang terjadi (biasanya kesalahan tidak akan dianggap sebagai peristiwa dalam pengertian ini, meskipun kami mungkin masih memilih untuk mencatatnya dalam log diagnostik). Sekarang, jikasend message
perintah diterima,message sent
acara terjadi, dan detail acara dapat menggambarkan pengirim, penerima, dan konten.Ketika kita berbicara tentang status sistem, kita sebenarnya membahas bukan puncak dari perintah, tetapi tentang peristiwa. Hanya acara yang dapat menyebabkan perubahan status dalam sistem. Untuk menarik dari contoh kehidupan, misalkan saya pergi ke supermarket Publix lokal dan membeli tiket lotere Florida. Perintahnya adalah "Beli Tiket" dan acara itu "Tiket dikeluarkan." Perintah saya selanjutnya adalah lotre untuk menggambar nomor saya untuk PowerBall. Lotre akan mengabaikan perintah saya (tapi saya tidak tahu), dan acara "nomor PowerBall terpilih" terjadi terlepas dari keinginan saya. Jika nomor saya cocok, acara "Jackpot won" terjadi pada saya (dan saya pikir perintah saya didengar). Jika tidak, saya menyadari bahwa perintah saya diabaikan.
Dari perspektif sejarah, lotere hanya tertarik pada sebagian dari peristiwa. Lotre hanya peduli bahwa (a) tiket dikeluarkan, (b) nomor dipilih, dan (c) jackpot dimenangkan. Itu adalah item yang menarik. Tindakan membeli tiket, ingin menang, dll. Semua tidak relevan, seperti apa yang saya lakukan dengan tiket saya setelah saya kalah. Sementara dunia nyata memang berubah untuk peristiwa duniawi, kita hanya perlu mencatat peristiwa-peristiwa yang penting bagi sistem kita.
Secara teori, di bawah teknik event-sourcing, aliran peristiwa dapat diputar ulang dari awal waktu untuk sampai pada keadaan saat ini. Ini bergantung pada asumsi bahwa kondisi sistem yang mendasarinya adalah konstan dan deterministik. Namun, asumsi ini tidak berlaku di banyak sistem. Data yang terkait dengan suatu peristiwa, serta jenis peristiwa yang kami minati, dapat berubah seiring berkembangnya perangkat lunak komputer kami. Selain itu, komputasi dapat menjadi mahal untuk menghitung kembali keadaan saat ini sebagai respons atas setiap permintaan. Untuk alasan ini, snapshot dari keadaan sistem sering diambil untuk mewakili titik waktu yang diketahui, yang kemudian ditambahkan ke sebagian besar peristiwa terkini.
Meskipun masih mungkin untuk memutar ulang arus peristiwa di berbagai versi, jumlah upaya manusia yang terlibat dalam melakukan hal itu kemungkinan akan menjadi penghalang biaya. Kecuali jika ada alasan yang dapat dibenarkan untuk merancang kemampuan itu ke dalam sistem, Anda lebih baik membangun sistem Anda untuk memanfaatkan snapshot.
Contoh dalam Pertanyaan
Dalam contoh yang diberikan dalam pertanyaan, arsitektur tidak benar-benar berbasis peristiwa; berbasis perintah. Memutar perintah menciptakan status sistem. Ini anti-pola dan harus diperbaiki. Sebaliknya, acara utama adalah:
Setiap peristiwa ini dapat "diputar ulang" untuk memberikan kondisi saat ini. Misalnya, dalam tindakan mengajukan pertanyaan, perilaku sistem mungkin mengirim email ke penjual dan menambah
unanswered question
penghitung. Perilaku ini dapat diubah; Namun, fakta bahwa pertanyaan itu diajukan tidak. Demikian pula, sistem dapat mengurangiunanswered question
konter ketika penjual merespons. Perilaku ini dapat diubah, tetapi kenyataan bahwa penjual merespons tidak.Sebagian besar sistem sumber acara akan menghitung secara dinamis jumlah pertanyaan yang tidak terjawab dengan memutar ulang arus peristiwa spesifik sebagai respons terhadap kueri.
sumber
Untuk audit, tentu saja. Untuk memulihkan ? Itu aneh, dan mungkin menyebabkan Anda sakit kepala.
Jika Anda akan menjadi sumber acara, Anda ingin rehydrating state dari peristiwa (hal-hal yang terjadi di masa lalu) bukan perintah. Ini menyelamatkan Anda dari sebagian besar masalah yang terkait dengan perubahan pada implementasi perintah - Anda hanya perlu berurusan dengan perubahan status yang ada.
Versi masih menjadi perhatian. Secara khusus, Anda ingin memastikan bahwa acara Anda yang bertahan setinggi mungkin (representasi DTO, daripada serialisasi langsung dari konsep-konsep di domain Anda). Saat membaca acara dari toko, Anda memiliki kesempatan untuk memperbaruinya seperlunya sebelum menerapkannya ke keadaan rehidrasi.
sumber