事件溯源模式

概念解釋

事件溯源(Event Sourcing)是一種設計模式,其核心思想是將系統的狀態變化表示為一系列不可變的事件,并將這些事件存儲在事件日志中。系統的當前狀態可以通過重新應用(回放)這些事件來還原,從而實現狀態的追溯。

傳統方式

大多數應用程序會使用數據,而典型的方法是用戶使用數據時通過立即更新數據使應用程序保持數據的當前狀態。 例如,在傳統的創建、讀取、更新和刪除 (CRUD) 模型中,典型的數據處理是從存儲讀取數據、對其作出修改、使用新值更新數據的當前狀態。

CRUD 方法具有一些限制:

  • CRUD 系統直接對數據存儲執行更新操作。 這些操作所需的處理工作開銷可能會降低性能和響應能力,并會限制可擴展性。
  • 在包含多個并發用戶的協作域中,由于會對數據單個項進行更新操作,因此出現數據更新沖突的可能性更大。
  • 除非有其他審核機制可以單獨記錄每個操作的詳細信息,否則歷史記錄會丟失。

事件溯源模式優點

  • 事件不可變,并且可使用只追加操作進行存儲。 用戶界面、工作流或啟動事件的進程可繼續,處理事件的任務可在后臺運行。
  • ?事件不會直接更新數據存儲。 只會對事件進行記錄,以便在合適的時間進行處理。 使用事件可簡化實現和管理
  • 事件溯源不需要直接更新數據存儲中的對象,因而有助于防止并發更新造成沖突。 但是,域模型必須仍然設計為避免可能導致不一致狀態的請求。
  • 事件的只追加存儲提供的審核線索可用于監視對數據存儲采取的操作。 它可以通過隨時重播事件將當前狀態重新生成為具體化視圖或投影,并且可以幫助測試和調試系統,事件列表還可用于分析應用程序性能和檢測用戶行為趨勢。

事件溯源模式缺點

  • 只有通過重播事件創建具體化視圖或生成數據投影時,系統才可實現最終一致性。 應用程序將事件添加到事件存儲作為處理請求的結果、發布事件和事件使用者處理事件之間存在一定程度的延遲。 在此期間,描述實體的進一步更改的新事件可能已到達事件存儲。 系統設計應考慮到這些方案中實現最終一致性

問題和注意事項

事件存儲是信息的永久源,因此請勿更新事件數據。 更新實體以撤銷更改的唯一方式是將補償事件添加到事件存儲。 如果持久化事件的格式(而不是數據)需要更改,也許在遷移期間,很難將存儲中的現有事件和新版本結合。 可能需要循環訪問所有事件進行更改,使其符合新格式,或添加使用新格式的新事件。 考慮在事件架構的每個版本上使用版本標記,以同時保留事件的舊格式和新格式。

多線程應用程序和應用程序的多個實例可能將事件存儲在事件存儲中。 事件存儲中的事件一致性至關重要,影響特定實體的事件的順序(實體更改發生的順序會影響當前狀態)同樣至關重要。 將時間戳添加到每個事件有助于避免出現問題。 另一常見做法是使用增量標識符注釋請求引起的每個事件。 如果兩個操作嘗試同時為同一實體添加事件,則事件存儲可拒絕與現有實體標識符和事件標識符相匹配的事件。

讀取事件以獲取信息并沒有標準方法或現有機制,例如 SQL 查詢。 可提取的唯一數據是將事件標識符用作條件的事件流。 事件 ID 通常會映射到各個實體。 僅可根據實體原始狀態通過重播與其關聯的所有事件來確定實體的當前狀態。

每個事件流的長度會影響管理和更新系統。 如果是大型流,請考慮按特定間隔(例如指定數量的事件)創建快照。 可通過快照和重播此時間點后發生的事件獲取實體的當前狀態。

即使事件溯源會最大程度降低數據更新沖突的可能性,應用程序仍必須能夠處理由最終一致性和缺少事務引起的不一致性。 例如,在指示存貨減少的事件到達數據存儲時,客戶可能正在對該商品下訂單。 這種情況導致需要在這兩個操作之間作出協調,即通知客戶或創建延期交付訂單。

事件發布可能是“至少一次”,因此事件使用者必須是冪等的。 如果事件處理次數大于 1,則使用者不得重新應用該事件中描述的更新。 使用者 cn 的多個實例維護并聚合實體的屬性,例如已下訂單總數。 下訂單事件發生時,只有一個實例必須成功遞增聚合。 盡管這個結果不是事件溯源的主要特點,但卻是通常的實現決策。

事件在事件存儲中持久化,事件存儲充當數據當前狀態的記錄系統(權威數據源)。 事件存儲通常會發布這些事件,訂閱者可收到通知并在需要時對其進行處理。請注意,生成事件的應用程序代碼應與訂閱到事件的系統分離。

所選的事件存儲需要支持由應用程序生成的事件負載。
請注意以下情況:處理一個事件會涉及創建一個或多個新事件,因為這可能會導致無限循環。

何時使用此模式

請在以下方案中使用此模式:

  • 要捕獲數據中的意圖、用途或原因。 例如,可將對客戶實體的更改捕獲為一系列特定事件類型,例如“已搬家”、“帳戶已關閉”或“已身故”。

  • 盡量減少或完全避免出現數據更新沖突。

  • 需要記錄發生的事件,并重播事件以還原系統狀態、回滾更改或保留歷史記錄和審核日志。 例如,任務涉及多個步驟時,可能需要執行操作來恢復更新,并重播某些步驟使數據重返一致的狀態。

  • 使用事件時。 這是應用程序操作的自然功能,且幾乎不需要其他開發或實現工作。

  • 需要將輸入或更新數據的過程從應用這些操作所需的任務中分離。 此更改可能是為了提高 UI 的性能,或者是為了將事件分發給其他在事件發生時采取操作的偵聽器。 例如,可以將工資管理系統與開支報銷網站集成。 由事件存儲引發的用于響應網站中數據更新的事件可同時供該網站和工資管理系統使用。

  • 希望隨要求更改而靈活更改具體化模型和實體數據的格式,或需要調整讀取模型或公開數據的視圖(與 CQRS 結合使用時)。

  • 與 CQRS 結合使用且更新讀取模型時最終一致性可接受或事件流中的解凍實體和數據的性能影響可接受。

此模式在以下情況中可能不起作用:

  • 小型域或簡單域、幾乎或完全沒有業務邏輯的系統或者自然地適用于傳統 CRUD 數據管理機制的非域系統。

  • 要求一致性和數據視圖實時更新的系統。

  • 不需要審核線索、歷史記錄以及回滾和重播操作功能的系統。

  • 基礎數據更新沖突發生率低的系統。 例如,主要是添加數據而不是更新數據的系統。

示例

會議管理系統需要跟蹤會議的已完成預訂數。 這種方式可以檢查潛在與會者預訂時是否有可用席位。 此系統可通過至少兩種方式存儲會議的預訂總數:

  • 此系統可將預訂總數信息作為單獨的實體存儲在包含預訂信息的數據庫中。 進行預訂或取消預訂時,此系統可相應地增加或減少此數量。 理論上而言,此方式很簡單,但如果短時間內有大量與會者嘗試預訂席位,則可能導致可伸縮性問題。 例如,在預訂期結束前的最后一天左右。

  • 此系統可將預訂和取消預訂信息存儲為事件存儲中的事件。 可通過重播這些事件來計算可用的席位數。 由于事件的不變性,此方式更具伸縮性。 此系統僅需要可從事件存儲讀取數據,或將數據追加到事件存儲。 不會修改有關預訂和取消預訂的事件信息。

下圖說明了如何使用事件溯源實施會議管理系統的席位預訂子系統。

使用事件溯源捕獲會議管理系統中有關席位預訂的信息

預訂兩個席位的操作順序如下:

  1. 用戶界面發出為兩位與會者預訂席位的命令。 該命令由單獨的命令處理程序處理。 一條邏輯,此邏輯從用戶界面分離且負責處理發布為命令的請求。

  2. 通過查詢描述預訂和取消預訂的事件,構造包含有關會議的所有預訂的信息的一個聚合。 此聚合名為?SeatAvailability,且包含在公開此聚合中數據的查詢和修改方法的域模型中。

    需要考慮的一些優化是使用快照(使獲取聚合的當前狀態無需查詢和重播事件的完整列表)和將此聚合的緩存副本保留在內存中。

  3. 命令處理程序調用域模型公開的方法來進行預訂。

  4. SeatAvailability?聚合會記錄包含已預訂席位數的事件。 聚合下次應用事件時,會使用所有的預訂數來計算剩余的席位數。

  5. 此系統將新事件追加到事件存儲中的事件列表。

如果某位用戶取消席位,此系統將執行相似過程,但命令處理程序會發出生成席位取消事件并將其追加到事件存儲的命令。

除了擴大可伸縮性范圍外,使用事件存儲還可提供會議預訂和取消預訂的完整歷史記錄或審核線索。 事件存儲中的事件是準確的記錄。 無需以其他任何方式持久化聚合,因為此系統可輕松重播事件并將狀態還原到任意時間點。

結論

通常配合CQRS模式結合使用,適用于大型應用系統,帶來便利的同時也需要考慮更多潛在且復雜的問題,如事件與實體之間的最終一致性、延遲等問題。一般小項目還是算了。不過是個很優秀的設計理念,有借鑒價值。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/162735.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/162735.shtml
英文地址,請注明出處:http://en.pswp.cn/news/162735.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

芯片的測試方法

半導體的生產流程包括晶圓制造和封裝測試,在這兩個環節中分別需要完成晶圓檢測(CP, Circuit Probing)和成品測試(FT, Final Test)。無論哪個環節,要測試芯片的各項功能指標均須完成兩個步驟:一是將芯片的引腳與測試機的功能模塊連接起來&…

促進材料基因工程基礎理論、前沿技術和關鍵裝備的發展和應用,第七屆材料基因工程高層論壇將于12月重慶舉辦,龍訊曠騰出席會議

為了進一步促進材料基因工程基礎理論、前沿技術和關鍵裝備的發展和應用,加強國際交流,加速我國新材料的研發和應用,由中國材料研究學會、西部科學城重慶高新區管理委員會主辦,重慶大學、北京科技大學、北京云智材料大數據研究院等…

【GUI】-- 14 GUI編程總結

GUI編程 05 GUI總結 在總結之前,先給出之前的貪吃蛇小游戲全代碼。 游戲的主啟動類: package com.duo.snake;import javax.swing.*;//游戲的主啟動類 public class StartGame {public static void main(String[] args) {JFrame frame new JFrame();…

Java面試-微服務篇-SpringCloud

Java面試-微服務篇-SpringCloud SpringCloud 常見組件注冊中心Eureka, Nacos負載均衡Ribbon服務雪崩, 熔斷降級微服務的監控來源 SpringCloud 常見組件 通常情況下 Eureka: 注冊中心Ribbon: 負載均衡Feign: 遠程調用Hystrix: 服務熔斷Zuul/Gateway: 網關 SpringCloudAlibaba…

【開源】基于Vue.js的天然氣工程運維系統的設計和實現

項目編號: S 022 ,文末獲取源碼。 \color{red}{項目編號:S022,文末獲取源碼。} 項目編號:S022,文末獲取源碼。 目錄 一、摘要1.1 項目介紹1.2 項目錄屏 二、功能模塊2.1 系統角色分類2.2 核心功能2.2.1 流程…

服務限流算法:從令人頭疼到信手拈來

前言 隨著系統規模的擴大和用戶量的增加,服務限流成為了一個非常重要的話題。一方面,系統需要能夠處理大量的請求,不至于因為負載過高而崩潰;另一方面,又需要避免惡意攻擊或者其他異常情況對系統造成影響。本文將介紹…

npm相關和私有云

安裝node時npm會自動安裝,npm也可以單獨安裝。 package.json 在使用npm時,package.json文件是非常重要的,因為它包含了關于項目的必要信息,比如名稱、版本、依賴項等。在初始化新項目時,通常會使用npm init命令生成一…

pip安裝python包到指定python版本下

python -m pip install 包名1.命令行進入到指定python安裝目錄。比如我電腦上有python3.8也有python3.9。準備給python3.9安裝指定的包

【青書學堂】 2023年第二學期 HTML5+CSS3(直播課) 作業

【青書學堂】 2023年第二學期 HTML5CSS3(直播課) 作業 為了方便日后復習,青書學堂成人大專試題整理。 若有未整理的課程,請私信我補充,歡迎愛學習的同學們收藏點贊關注!文章內容僅限學習使用!!!…

3.OpenFeign的使用

OpenFeign 文章目錄 OpenFeign一. 什么是OpenFeign二. OpenFeign基礎使用1.添加依賴2.配置Nacos配置信息3.在項目中開啟OpenFeign4.編寫OpenFeign調用代碼5.調用OpenFeign接口 三. OpenFeign內置的超時重試機制1.配置超時重試2.覆蓋Retryer對象 四.自定義超時重試機制1.自定義超…

Hive中常出現的錯誤(不定時更新)

1.加載數據失敗 hive> load data local inpath /home/user/hive.txt into table studentl> ; FAILED: SemanticException [Error 10001]: Line 1:56 Table not found studentl hive> load data local inpath /home/user/hive.txt into table student; Loading data to…

技術分享| anyRTC之RTN網絡

RTN(Real-time Network)中文名:實時音視頻傳輸網絡。 RTN是最近幾年由各大RTC的云廠商提出的一個全新架構的音視頻實時傳輸網絡概念。類似于直播的CDN網絡,RTN是對音視頻的實時性又強烈要求的場景而設計的,原理上全球端到端的時延通過RTN網絡…

JSP EL表達式獲取list/Map集合與java Bean對象

上文 JSP EL表達式基本使用 中 我們對EL表達式做了一個基本的了解 也做了基礎的字符串數據使用 那么 我們可以來看一下我們的集合 首先 list 這個比較簡單 我們直接這樣寫代碼 <% page import"java.util.ArrayList" %> <% page import"java.util.Lis…

基于C#實現優先隊列

一、堆結構 1.1性質 堆是一種很松散的序結構樹&#xff0c;只保存了父節點和孩子節點的大小關系&#xff0c;并不規定左右孩子的大小&#xff0c;不像排序樹那樣嚴格&#xff0c;又因為堆是一種完全二叉樹&#xff0c;設節點為 i,則 i/2 是 i 的父節點&#xff0c;2i 是 i 的…

安卓開發之HTTP API服務接口設計(基于okhttp3請求)

安卓中的請求 OkHttp3 是一個開源的 Java/Android HTTP 客戶端庫,由 Square 公司開發。它提供了簡潔和高效 的 API ,用于進行 HTTP 請求、處理響應以及與服務器進行通信。 以下是 OkHttp3 的一些主要特點和功能: 簡單易用: OkHttp3 提供了簡潔的 API ,使得發送 HTTP 請求變…

信息系統的安全保護等級的五個級別

信息系統的安全保護等級分為五級&#xff1a;第一級為自主保護級、第二級為指導保護級、第三級為監督保護級、第四級為強制保護級、第五級為專控保護級。 法律依據&#xff1a;《信息安全等級保護管理辦法》第四條 信息系統的安全保護等級分為以下五級&#xff1a;   &#…

【C語言】計算實時太陽角度(高度角、方位角),以及使用stm32單片機實時獲取時間戳

整體計算方法 在編寫該代碼的過程中尋找了多篇博文和論文&#xff0c;綜合所有文章且按網上的以0時的方位角的0&#xff0c;且隨時間累加累加至360度。我修改了博文和論文的一些角度的計算方法。得到一下代碼與網站計算的方位角相互驗證過&#xff0c;誤差不超過1 驗證網站 太…

LoRaWAN 中國地區文件詳細解讀

目錄 一、LoRaWAN簡介 二、CN470-510地區參數分析 1.信道頻率 2.支持功率 3.支持空速 4.最大負載大小 5.接受窗口參數 三、CN470_510默認參數 Lora LoraWAN教程 一、LoRaWAN簡介 LoraWAN是一種基于LoRa遠距離通信技術配套設計的一套通訊協議和系統架構。LoRaWAN網絡通…

Java實現拼圖游戲

1、了解拼圖游戲基本功能&#xff1a; 拼圖游戲內容由若干小圖像塊組成的&#xff0c;通過鼠標點擊圖像塊上下左右移動&#xff0c;完成圖像的拼湊。 2、拼圖游戲交互界面設計與開發&#xff1a; 通過創建窗體類、菜單、中間面板和左右面板完成設計拼圖的交互界面 &#xff…