命令和事件有什麼區別? - Oskar
命令代表意圖:它針對特定的受眾。當你問“把鹽遞給我”時,它可以是你的朋友。它可以是一個應用服務和請求,意圖是“新增使用者”或“將訂單狀態更改為已確認”。所以命令的傳送者必須知道接收者並期望請求被執行。當然,接收者可能會拒絕這樣做,因為在請求處理期間不向我們傳遞鹽或丟擲異常。
事件代表了過去的事實:它攜帶有關已完成某事的資訊。所見所聞,不可不察。按照我們的例子“使用者新增”,“訂單狀態更改為確認”是過去的事實。我們不會將事件定向到特定的接收者,我們會廣播資訊。這就像在聚會上講故事一樣。我們希望有人傾聽我們,但我們可能很快就會意識到沒有人在關注。
事件和命令有什麼共同點?
兩者都是訊息。它們傳達特定的資訊;關於做某事的意圖的命令,或關於發生的事實的事件。從計算機的角度來看,它們沒有什麼不同。只有業務邏輯和訊息的解釋才能發現事件和命令的區別。
通常假設命令是同步的,而事件是非同步的。我們通常透過例如 Rest API 傳送命令,透過佇列(記憶體中、RabbitMQ、Kafka 等)傳送事件。這種區別來自習慣。當我們傳送命令時,我們想立即知道它是否已經完成。通常,我們希望在操作失敗時進行替代方案或錯誤處理。同樣,我們通常假設最好立即停止該過程,例如購買電影票,而不是等待並重新整理並檢視它是否有效。
這是有道理的,但並不總是那麼明顯。例如,銀行轉賬:當我們成功時,它不會立即發生。我們得等一會兒。在 Internet 上進行購買時也是如此。下訂單和付款不會立即完成整個過程。它還是要發貨,發票開具等等。這是一個非同步過程,所以我們的命令的結果也可能是非同步的。
微服務和分散式系統增加了額外的複雜性。
傳統上,發件人需要知道該告訴誰來接管其餘的工作。使用排隊/流系統逆轉服務的依賴性。傳送者將訊息釋出到統一頻道,接收者訂閱並等待。當我們購買電影票時,必須生成收據,必須預訂座位,並透過電子郵件通知使用者並在網站上顯示。所有這些都可以拆分為單獨的工作流程步驟。哪個應該由命令觸發,哪個應該由事件觸發?
我們可以使用啟發式:當接收者有權拒絕請求時,我們傳送命令,當接收者接受時傳送事件。如果我們要新增使用者,系統可能會拒絕我們使用現有使用者名稱。金融服務可以拒絕預訂服務生成收據嗎?如果預訂被確認,轉賬已經完成,那麼財務模組應該接受它。那麼,這是一個事件嗎?
理論上,是的,如果沒有驗證規則並且事件發生了,另一個系統應該接受它並執行邏輯。即使金融服務暫時不可用,類似 Kafka 的流媒體系統也應保證交付。我們在程式碼中有錯誤?然後我們必須修復它們。
到這裡,理論結束,實踐開始。我們的客戶不在乎錯誤是否是我們知道並在不久的將來修復的錯誤?客戶想要開展業務並運營。
當然,在訊息佇列教程中,你可以找到這樣的建議:“有一個死信佇列/毒訊息佇列,未處理的訊息將被放置在那裡。你可以在那裡檢查並做出反應”。這很酷,但有多少人在監視它?即使他們這樣做了,他們能多快做出反應?假設我們收集指標、傳送警報、快速支援響應並向程式設計師報告“票”。他們會多快修復它?我們可以透過預先設計並新增補償操作(例如,如果預訂確認事件丟失時在 UI 中生成發票的按鈕)來簡化這一點。
有時事實證明,一個給定的事件總是隻有一個接收者。更重要的是,我們希望它始終得到處理。它仍然是一個事件嗎?值得考慮的是,在名稱為“預訂已確認”的事件下,我們是否不傳送“發出收據”命令。當業務流程至關重要時,我們可能更願意快速失敗並立即獲得結果。對於這種情況,值得考慮是否執行非同步命令比執行非同步事件更好。
命令和事件之間的區別可能並不像看起來那麼簡單。我們需要考慮很多因素:
- 是有意做某事還是記錄的事實?
- 是非同步操作還是同步操作?
- 它可以有多個收件人嗎?
- 它是關鍵業務嗎?
- 還有很多
如果有人問你“這是一個命令還是一個事件”,不要害怕說“這取決於”,然後開始著手理解業務邏輯。
相關文章
- React事件與普通HTML事件有什麼區別React事件HTML
- 滑鼠事件css的:hover和js的mouseover有什麼區別?事件CSSJS
- node的事件迴圈和瀏覽器的事件迴圈有什麼區別?事件瀏覽器
- shim和polyfill有什麼區別
- vue和react有什麼區別?VueReact
- modbus和tcp有什麼區別?TCP
- Jsp和Servlet有什麼區別?JSServlet
- SpringBoot和Spring有什麼區別?Spring Boot
- Cache 和 Buffer 有什麼區別?
- RPA和IPA有什麼區別
- int 和 Integer 有什麼區別
- rancher 和 Kubernetes有什麼區別?
- QPS和TPS有什麼區別?
- Hifi和ONT 有什麼區別
- Iterator和ListIterator有什麼區別
- DOM和BOM有什麼區別?
- xpath和dom有什麼區別?
- Activity和Fragment有什麼區別Fragment
- HTTP和HTTPS有什麼區別?HTTP
- mongodb和mysql有什麼區別MongoDBMySql
- python和nodejs有什麼區別PythonNodeJS
- VPS和HTTP有什麼區別?HTTP
- session 和 cookie 有什麼區別?SessionCookie
- float和double有什麼區別?
- @Controller和@RestController有什麼區別?ControllerREST
- cookie和session 有什麼區別?CookieSession
- ReferenceError和TypeError有什麼區別?Error
- cookie是什麼?和session有什麼區別?CookieSession
- Java和Python是什麼?有什麼區別?JavaPython
- 什麼是 MicroPython?和CPython有什麼區別?Python
- IPFS和區塊鏈有什麼區別區塊鏈
- Linux中apt和apt-get命令有什麼區別?如何使用?Linuxapt-get
- Linux中su和sudo命令有什麼區別?Linux學習教程Linux
- xpgu是什麼 xgpu和xgp有什麼區別GPU
- Python語言中=和==有什麼區別?Python
- JMS和AMQP有什麼區別嗎MQ
- maven </dependencies>和</dependencyManagement> 有什麼區別Maven
- Linux的3種“複製”命令有什麼區別?Linux