CQRS + Tìm nguồn sự kiện: (có đúng không) Các lệnh thường được truyền đạt điểm-điểm, trong khi Sự kiện miền được truyền thông qua pub / sub?


12

Về cơ bản, tôi đang cố gắng che giấu khái niệm về CQRS và các khái niệm liên quan.

Mặc dù CQRS không nhất thiết phải kết hợp Nguồn tin nhắn và sự kiện, nó dường như là một sự kết hợp tốt (có thể thấy với rất nhiều ví dụ / blogpost kết hợp các khái niệm này)

Đưa ra một trường hợp sử dụng cho một thay đổi trạng thái cho một cái gì đó (nói để cập nhật Câu hỏi về SO), bạn có xem xét các luồng sau đây là chính xác (như trong thực tiễn tốt nhất) không?

Hệ thống đưa ra một UpdateQuestionCommand tổng hợp có thể được tách thành một vài lệnh nhỏ hơn: UpdateQuestion được nhắm mục tiêu tại Root Aggregate Root và UpdateUserAction (để đếm điểm, v.v.) nhắm vào Root tổng hợp người dùng. Chúng được gửi không đồng bộ bằng cách sử dụng tin nhắn điểm-điểm.

Các gốc tổng hợp thực hiện công việc của chúng và nếu tất cả đều diễn ra tốt các sự kiện tương ứng là Câu hỏi khởi tạo và UserActionUpdated, có chứa trạng thái được gia công cho Cửa hàng sự kiện .. để được yadayada kiên trì, chỉ cần hoàn thành, không thực sự là điểm chính ở đây.

Những sự kiện này cũng được đưa vào hàng đợi quán rượu / phụ để phát sóng. Bất kỳ người đăng ký nào (trong đó có khả năng một hoặc nhiều Máy chiếu tạo Chế độ xem Đọc) đều được đăng ký miễn phí các sự kiện này.

Câu hỏi chung: Có thực sự tốt nhất không, rằng các Lệnh được truyền đạt Điểm-Điểm (nghĩa là: Người nhận được biết) trong khi các sự kiện được phát (Tức là: người nhận không biết)?

Giả sử như trên, điều gì sẽ là lợi thế / bất lợi của việc cho phép các Lệnh được phát qua pub / sub thay vì điểm-điểm?

Ví dụ: Khi phát các Lệnh trong khi sử dụng Saga có thể là một vấn đề, vì vai trò hòa giải mà Saga cần phát trong trường hợp thất bại của một trong những gốc tổng hợp bị cản trở, bởi vì saga không biết bắt nguồn từ rễ tổng hợp nào để bắt đầu .

Mặt khác, tôi thấy những lợi thế (tính linh hoạt) khi các lệnh phát sóng sẽ được cho phép.


Câu hỏi được viết tốt btw.
Dav

Câu trả lời:


18

Tuyên bố miễn trừ trách nhiệm: Tôi chỉ mới thực hiện những bước đầu tiên trong thế giới CQRS, nhưng tôi có thể cung cấp hiểu biết hiện tại về vấn đề này và chúng tôi sẽ xem liệu những người khác có xác nhận hay không. Tất cả những gì tôi viết dưới đây có một chủ đề "như tôi thấy", và không có thẩm quyền.

80% trường hợp

Để trả lời câu hỏi của bạn, các lệnh thực sự là một vấn đề điểm-điểm. Khi một lệnh vào một bộ điều khiển (ứng dụng web MVC), bộ điều khiển đó sẽ yêu cầu một bộ điều phối lệnh tìm một và chỉ một trình xử lý lệnh apropitable và ủy thác công việc cho trình xử lý đó.

Tại sao không công bố?

Đó là một câu hỏi về trách nhiệm . Nếu một cái gì đó gửi một lệnh, nó đòi hỏi kỳ vọng rằng nó sẽ được thực hiện. Nếu bạn chỉ đơn giản xuất bản và hy vọng rằng một cái gì đó ở đâu đó nhặt nó lên và hành động trên nó, không có gì đảm bảo rằng đây sẽ là trường hợp. Bằng phép ngoại suy, bạn cũng không biết nếu nhiều trình xử lý không quyết định hành động theo lệnh, có thể dẫn đến cùng một thay đổi được áp dụng nhiều lần.

Mặt khác, các sự kiện có nhiều thông tin về bản chất và thật hợp lý khi mong đợi không, hai hoặc nhiều thành phần quan tâm đến một sự kiện cụ thể. Chúng tôi không thực sự quan tâm trong phạm vi thực hiện thay đổi được yêu cầu.

Thí dụ

Điều này có thể được so sánh với cuộc sống thực. Nếu bạn có ba đứa con, hãy bước vào một căn phòng và chỉ cần hét lên "Dọn dẹp phòng tắm", bạn không có gì đảm bảo rằng ai đó sẽ làm điều đó và nói xấu nếu điều đó không được thực hiện hai lần (nếu bạn có những đứa trẻ ngoan ngoãn ;-) Bạn nên giá vé tốt hơn nếu bạn chỉ định một đứa trẻ cụ thể để làm những gì bạn muốn làm.

Tuy nhiên, khi đứa trẻ đó hoàn thành công việc của mình, thật tiện lợi nếu nó hét lên "phòng tắm đã được dọn sạch", để mọi người muốn đánh răng đều biết giờ họ có thể làm như vậy.


Hãy làm cho nó thêm ý nghĩa hơn. Sự tương tự tuyệt vời :)
Geert-Jan

Bạn mất tôi lúc .. When a command enters a controller (MVC webapp)-? Bạn đang sử dụng RESTful? hoặc một số điểm cuối API lai? Bạn có thể thêm một ví dụ xin vui lòng
Piotr Kula

@ppumkin, chúng tôi đã sử dụng điểm cuối WebAPI sẽ được gọi bởi ứng dụng web của chúng tôi mỗi khi cần thực thi lệnh. Ví dụ. nếu người dùng muốn thêm một bình luận bài viết, ứng dụng web sẽ gửi yêu cầu POST đến example.com/api/Post/AddPostComment.
Dav

1

Tôi đồng ý rằng một hệ thống khởi tạo thường sẽ không bao giờ mong đợi một lệnh được giao dịch bởi nhiều hệ thống đích:

  • Các lệnh thường không bao giờ 'gửi và cầu nguyện' - hệ thống khởi tạo của lệnh thường muốn phản hồi không đồng bộ khi tiến trình và kết quả của lệnh diễn ra (ví dụ: các sự kiện trạng thái như acknowledgement, và thành công completionhoặc failurecó thể được xuất bản bởi hệ thống được nhắm mục tiêu hệ thống).
  • Nếu có nhiều hệ thống đích được tham gia, hệ thống khởi tạo sẽ nhận được nhiều kết quả (có thể mâu thuẫn) cho lệnh (ví dụ: mục tiêu 1 đã thành công, nhưng mục tiêu 2 không thành công). Điều này sẽ đòi hỏi sự phức tạp bổ sung trong việc xác định trạng thái thực tế của lệnh ban đầu (ví dụ: giao dịch lệnh chỉ được coi là thành công nếu tất cả các mục tiêu thành công? Lệnh có cần được khôi phục hoặc bù vào các mục tiêu thành công nếu một trong các mục tiêu không thành công? Vân vân.). Điều này sẽ giới thiệu sự kết hợp và độ phức tạp không mong muốn giữa các hệ thống khởi tạo và mục tiêu.

Tuy nhiên, vẫn có công khi có thể đăng ký thêm người tiêu dùng (không giao dịch và thường khá 'lăng nhăng'), những người 'nghe lén' các lệnh được ban hành giữa các hệ thống

  • Mục đích kiểm toán
  • Các số liệu về thiết bị và hoạt động (ví dụ: tải, phân tích kinh doanh, v.v.)
  • Xử lý sự kiện phức tạp hoặc Xử lý luồng sự kiện 'nghe lén' - các hệ thống này có thể phát hiện lỗi hoặc bất thường trong các lệnh (ví dụ: tần suất của lệnh hoặc tương quan giữa các tổ hợp lệnh và sự kiện khác nhau) và có thể kích hoạt cảnh báo hoặc hành động khắc phục (thường trong hình thức hơn nữa, các loại lệnh khác nhau).
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.