CQRS + Olay Sağlama: (doğru mu?) Komutlar genellikle noktadan noktaya iletilirken, Etki Alanı Olayları pub / sub üzerinden iletilir mi?


12

Temelde kafamı CQRS ve ilgili kavramların etrafına sarmaya çalışıyorum .

CQRS, Mesajlaşma ve Etkinlik Kaynaklandırma'yı zorunlu olarak içermemesine rağmen, iyi bir kombinasyon gibi görünmektedir (bu kavramları birleştiren birçok örnek / blog yazısı ile görülebileceği gibi)

Bir şey için durum değişikliği için bir kullanım durumu göz önüne alındığında (SO ile ilgili bir Soruyu güncelleyin), aşağıdaki akışın doğru olduğunu düşünür müsünüz (en iyi uygulamada olduğu gibi)?

Sistem, birkaç küçük komuta ayrılabilen bir toplu UpdateQuestionCommand yayınlar: Soru Toplama Kökü'ne hedeflenen UpdateQuestion ve Kullanıcı Toplama Kökü'nü hedefleyen UpdateUserAction (noktaları saymak vb.). Bunlar, noktadan noktaya mesajlaşma kullanılarak senkronize olmayan bir şekilde gönderilir.

Toplam kökler kendi işlerini yaparlar ve eğer her şey yolunda giderse, sırasıyla bir Olay Deposuna dış kaynaklı durum içeren QuestionUpdated ve UserActionUpdated olaylarını tetikler.

Bu olaylar aynı zamanda yayın için bir pub / alt kuyruğuna konur. Herhangi bir abone (aralarında Okuma Görünümleri oluşturan bir veya birden fazla Projektör) bu etkinliklere abone olabilir.

Genel soru: En iyi uygulama Komutların Noktadan Noktaya iletilmesi (yani: Alıcı biliniyor), ancak olaylar yayınlanır (yani: alıcı (lar) bilinmemektedir)?

Yukarıdakileri varsayarsak, Komutların noktadan noktaya yerine pub / sub üzerinden yayınlanmasına izin vermenin avantajı / dezavantajı ne olurdu?

Örneğin: Saga'ları kullanırken Komutlar yayınlamak bir sorun olabilir, çünkü agrega köklerinden birinin başarısızlığı durumunda bir Saga'nın oynaması gereken arabuluculuk rolü engellenir, çünkü destan hangi toplu köklerin başlayacağını bilmez .

Diğer yandan, yayın komutlarına izin verildiğinde avantajlar (esneklik) görüyorum.


İyi yazılmış bir soru btw.
Dav

Yanıtlar:


19

Feragatname: CQRS dünyasında sadece ilk adımımı atıyorum, ancak konuyla ilgili şu anki anlayışımı sunabilirim ve başkalarının onaylayıp onaylamadığını göreceğiz. Aşağıda yazdığım tek şeyin altında "gördüğüm gibi" bir tema var ve yetkili değil.

% 80 vaka

Sorunuzu cevaplamak için, komutlar gerçekten noktadan noktaya bir meseledir. Bir komut bir denetleyiciye (MVC webapp) girdiğinde, o denetleyici bir komut dağıtıcıdan bir ve yalnızca bir uygun komut işleyicisi bulmasını ister ve işi bu işleyiciye devreder.

Neden yayınlamıyorsunuz?

Bu bir sorumluluk meselesi . Bir şey bir komut gönderirse, yerine getirileceği beklentisi doğar. Bir yerde bir şeyin onu alıp ona göre hareket ettiğini umuyorsanız ve yayınlarsanız , durumun böyle olacağının garantisi yoktur . Ekstrapolasyon ile, birden fazla işleyicinin bir komut üzerinde işlem yapmaya karar vermediğini de bilmiyorsunuz, bu da muhtemelen aynı değişikliğin birden fazla uygulanmasına neden oluyor.

Diğer yandan, olaylar doğası gereği bilgilendirici niteliktedir ve sıfır, iki veya daha fazla bileşenin belirli bir olayla ilgilenmesini beklemek mantıklıdır. İstenen değişikliği yapma konusunda gerçekten umursamıyoruz.

Misal

Bu gerçek hayatla karşılaştırılabilir. Üç çocuğunuz varsa, bir odaya girin ve sadece "Banyoyu temizle" diye bağırın, birinin yapacağını garanti etmezsiniz ve iki kez yapılmayacaksa canlanır (eğer itaatkar çocuklarınız varsa ;-) Yapmak istediğiniz şeyi yapmak için belirli bir çocuk atarsanız daha iyi ücret alın.

Ancak bu çocuk işini bitirdiğinde, “banyo temizlendi” diye bağırmak uygun olur, böylece dişlerini fırçalamak isteyen herkes artık bunu yapabileceklerini bilir.


çok mantıklı. Excellent analogy :)
Geert-Jan

Beni de kaybettin .. When a command enters a controller (MVC webapp)-? RESTful kullanıyor musunuz? veya bazı karma API uç noktaları? Lütfen bir örnek ekleyebilir misiniz
Piotr Kula

@ppumkin, bir komut yürütmek için her ihtiyaç duyulduğunda web uygulamamız tarafından çağrılacak bir WebAPI uç noktası kullandık. Örneğin. kullanıcı bir yorum yorumu eklemek isterse, web uygulaması adresine bir POST isteği gönderir example.com/api/Post/AddPostComment.
Dav

1

Bir başlatma sisteminin genellikle bir komutun birden fazla hedef sistem tarafından işlem görmesini asla beklemeyeceğine katılıyorum:

  • Komutlar genellikle hiçbir zaman 'gönderme ve dua etme' değildir - bir komutun başlatma sistemi genellikle komutun ilerlemesi ve sonucu gerçekleştikçe eşzamansız geri bildirim ister (örn. acknowledgement, Ve başarılı ve başarılı olan durum olayları completionveya failurehedeflenen sistem tarafından başlatılanı bilgilendirmek için yayınlanabilir) sistem).
  • Birden fazla hedef sistem söz konusuysa, başlatma sistemi komut için birden fazla (muhtemelen çelişkili) sonuç alacaktır (örneğin, hedef 1 başarılı olmuştur, ancak hedef 2 başarısız olmuştur). Bu, orijinal komutun gerçek durumunun belirlenmesinde ek karmaşıklık gerektirir (örn. Komut işlemi yalnızca tüm hedefler başarılı olursa başarılı sayılır mı? Hedeflerden biri başarısız olursa komutun geri alınması veya başarılı hedeflerde telafi edilmesi gerekir mi? vb.). Bu, başlatma ve hedef sistemler arasında istenmeyen birleşme ve karmaşıklık getirecektir.

Bununla birlikte, sistemler arasında verilen komutlara 'kulak misafiri olan' ek (işlemsel olmayan ve genellikle oldukça 'karışık') tüketicilere abone olmayı hak ediyor.

  • Denetim amaçları
  • Enstrümantasyon ve Operasyonel metrikler (ör. Yük, iş analizi, vb.)
  • Karmaşık Olay İşleme veya Akış Olay işleme 'kulak misafiri' - bu sistemler komutlardaki hataları veya düzensizlikleri algılayabilir (örn. Komutların sıklığı veya farklı komut ve olay kombinasyonları arasındaki korelasyon) ve uyarıları veya düzeltici eylemleri (genellikle daha farklı, farklı komut türleri).
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.