<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    從 CRUD 遷移到事件溯源的秘訣 - eventstore

    VSole2022-08-08 10:12:07

    事件溯源是高性能協作域的一種很好的架構風格,可以保證它增加的復雜性。但正如我之前所說,就像任何其他原則或實踐一樣,即使是事件溯源也有利有弊。而且它不是頂級架構。您系統的某些部分可能會從中受益,但其他部分可能不會。話雖如此,如果您需要事件溯源,并且您有一個現有的、更傳統的(又名 CRUD)應用程序,您可以遵循大致三種策略:

    1. 保持一切原樣,僅使用事件溯源構建系統的新部分
    2. 通過并排重建現有子系統或域來隱藏它。
    3. 然后,在重建完成后,切換所有現有消費者并自動遷移數據。
    4. 對現有域進行逐個實體的逐步遷移

    大約七年前,我們逐漸將使用命令查詢職責分離 (CQRS) 模式設計的現有 .NET 應用程序轉換為事件溯源。由于前兩個場景已經寫了很多,讓我分享我們為后者采取的秘訣。 

    讓我們從建立術語開始。在更傳統的系統中,您的域由實體組成。在事件溯源世界中,您經常會看到幾個相關實體形成了一個事務邊界。在領域驅動設計中,這稱為聚合。大多數事件存儲使用術語流來捕獲該聚合中曾經發生的所有事件。并且該聚合中通常有一個實體作為唯一的入口點。這是聚合根,由唯一編號或鍵(流 ID )標識。現在我們已經解決了這個問題,這里有一些實用的步驟來幫助你前進。

    1. 弄清楚您當前的域是否依賴于跨多個實體的事務,以及事件存儲實現是否支持跨聚合(或跨流)事務。
    2. 仔細決定哪些實體將形成聚合。
    3. 如果您的聚合太大,并且您還沒有準備好采用事件合并技術,則會增加用戶運行在樂觀并發問題中的機會。
    4. 如果您的聚合太小,并且您的事件存儲不支持跨聚合事務,則您必須以功能方式處理這些業務規則,例如,使用補償操作。
    5. 這就是為什么讓這些不變量幫助您定義聚合的邊界如此重要。
    6. 確定哪個實體應作為聚合根、聚合的入口點,并向其添加版本。
    7. 確保對聚合內實體的任何更改都會影響版本。
    8. 如果那里已經有一個版本,我們建議通過將事件數添加到原始版本號來計算新版本。
    9. 確保沒有其他代碼可以在不首先通過聚合根的情況下改變聚合內實體的狀態。
    10. 將子實體上的可寫屬性和公共方法替換為根上的方法,因此根控制訪問,可以保護業務規則,生成唯一的子 ID 并提高版本。
    11. 刪除跨聚合的實體之間的直接依賴關系。
    12. 例如,在對象關系映射器支持的許多域中,具有延遲加載屬性是很常見的。
    13. 您需要重構任何依賴于它的代碼,或者引入和注入存儲庫抽象。
    14. 確保實體不知道持久性并且不直接訪問數據庫。
    15. 要么將其移動到處理來自您的 API 的傳入請求的命令處理程序,要么為此引入存儲庫抽象。
    16. 為該聚合確定一個自然分區鍵,這樣您就可以在事件存儲變得非常大并導致性能問題或存儲問題的情況下拆分事件。
    17. 一個很好的分區鍵是以這樣一種方式分離數據的東西,您不需要跨分區處理業務規則。
    18. 例如,您的域可能是按地理區域或公司組織的。
    19. 在多租戶域中,租戶 ID 將是一個很好的候選者。
    20. 由于您不應修改歷史記錄,因此事件溯源中的刪除概念略有不同。
    21. 盡管您在技術上可以從底層事件存儲中刪除事件,但您通常會采用更實用的方法并使用事件將聚合標記為已刪除。
    22. 因此,任何用于請求實體的特定實例并準備好找不到任何內容的查詢都必須明確采用或通過某種抽象采用。
    23. 一個常見的解決方案是將 IsDeleted 屬性添加到存儲庫實現可以檢查的聚合根。
    24. 考慮數據導入需求。
    25. 如果您習慣于直接通過表導入數據,則必須將其更改為 CLI 或 HTTP API 之類的內容。
    26. 還要決定是要通過現有的“屬性更改”事件還是通過專門的“數據已導入”事件來處理該導入。
    27. 仔細確定如何將實體的原始鍵映射到流 ID。
    28. 大多數事件存儲支持使用字符串作為流 ID,但如果不經過一些更復雜的循環,就不可能在事后更改 ID。
    29. 如果您的商店僅使用 GUID,您可以使用像這樣的確定性 Guid 生成器。
    30. 并且不要忘記內部密鑰與您在域外公開的密鑰之間存在差異。
    31. 與此密切相關的是,在事件溯源中保證唯一性的工作方式略有不同。
    32. 因此,如果您的域依賴于數據庫模式來保護唯一約束,您將需要找到替代方案(例如使用流 ID)。
    33. 引入用于從/向事件存儲加載和保存聚合的基礎結構,并從持久化事件中重新混合聚合。
    34. 您可以在此處、此處和此處找到一些有關如何執行此操作的示例以及 .NET 中聚合根的基類。
    35. 到目前為止,我們主要使用這些參考作為示例,而不是作為框架來構建我們的域。
    36. 如果您有存儲庫抽象,請確保它知道哪些實體已轉換并需要從事件存儲中加載,哪些仍需要從原始表中加載。
    37. 為此,我們使用了標記接口或 .NET 屬性。
    38. 推遲諸如快照之類的決定,直到您需要它們為止。
    39. 對于最終具有大量事件的聚合來說,快照是一種有效的解決方案。
    40. 但是,在您獲得足夠的性能結果來保證這種復雜性之前,不要去那里。
    41. 決定如何將存儲在數據庫中的現有實體轉換為事件源聚合。
    42. 過去,我們試圖將現有記錄映射到單個的、更多“屬性更改”的事件中。
    43. 回想起來,我們應該已經定義了一次性轉換事件。
    44. 確定您是否希望使投影代碼在事務上與聚合發出的事件一致,以及這是否會給您可接受的性能。
    45. 如果您不這樣做,并且所有投影表都是異步構建的,請確保代碼庫的其余部分不希望投影表上的查詢保持一致。
    46. 設計將現有數據轉換為新的事件源模型的策略。
    47. 例如,這就是我們所做的:
    48. [list=1]
    49. 使用臨時名稱重命名現有表及其子表
    50. 一一讀取記錄并使用您在前面步驟中設計的事件構建新的聚合
    51. 將這些新事件投影到一組新的表中,這些表的名稱和結構與遷移開始前的樣子相同
    52. 轉換和投影后立即從臨時表中刪除每條記錄
    53. 刪除臨時表
    • 對其余實體重復前面的步驟,但不要猶豫,在生產中發布中間步驟。
    • 根據您的需要構建更優化的投影。
    • 但不要忘記,第一個目標是轉換您現有的代碼庫。
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    事件溯源是高性能協作域一種很好架構風格,可以保證它增加復雜性。但正如我之前所說,就像任何其他原則或實踐一樣,即使是事件溯源也有利有弊。而且它不是頂級架構。您系統某些部分可能會從中受益,但其他部分可能不會。話雖如此,如果您需要事件溯源,并且您有一個現有、更傳統(又名 CRUD)應用程序,您可以遵循大致三種策略:
    批處理用于每天為企業處理數十億交易。Spring Batch是一個輕量級,全面批處理框架,旨在開發對企業系統日常運營至關重要強大批處理應用程序。大批量批處理作業可以高度可擴展方式利用該框架來處理大量信息。以某種方式處理數據。什么是JobJob和Step是spring batch執行批處理任務最為核心兩個概念。其中Job是一個封裝整個批處理過程一個概念。
    這篇技術干貨 帶你了解深信服AI技術
    RedisJSON 橫空出世
    2021-12-21 16:18:23
    近期官網給出了RedisJson(RedisSearch)性能測試報告,可謂碾壓其他NoSQL,下面是核心報告內容,先上結論: 對于隔離寫入(isolated writes),RedisJSON 比 MongoDB 快 5.4 倍,比 ElasticSearch 快 200 倍以上。 對于隔離讀取(isolated reads),RedisJSON 比 MongoDB 快 12.7 倍,比
    領域服務建議邊界是子域,因為對于單個團隊來說,邊界不應太大。業務域通常是由多個子域組成大部分業務區域。實際上,它們在域中每個服務都代表該域一部分,我稱之為子域,但是您可以決定將其命名為不同東西。新構架,新問題毫無疑問,微服務已證明命名很重要。包括領域服務,API端點及其代表概念。去年,Uber在Uber上發布了面向領域微服務,向我們展示了微服務發展,使其更加注重領域。
    業務同學抱怨業務開發沒有技術含量,用不到設計模式、Java 高級特性、OOP,平時寫代碼都在堆?CRUD,個人成長無從談起。其實,我認為不是這樣。設計模式、OOP 是前輩們在大型項目中積累下來經驗,通過這些方法論來改善大型項目可維護性。
    //把Map購物車轉換為Item列表??//應付總價=商品總價+運費總價-優惠??然后實現針對 VIP 用戶購物車邏輯。所以,這部分代碼只需要額外處理多買折扣部分:public?
    InfoWorld 公布了 2022 年最佳開源軟件榜單。InfoWorld 2022 年 Bossie 獎旨在表彰年度最重要和最具創新性應用程序開發、devops、數據分析和機器學習工具。Redwood 允許針對各種部署環境,包括 Vercel 和 Netlify 等無服務器平臺。它允許拖放組件來構建儀表板、使用 JavaScript 對象編寫邏輯并連接任何 API、數據庫或 GraphQL 源。Spinnaker 是一個持續交付平臺,它定位于將產品快速且持續部署多種云平臺上。Spinnaker 主要特性:配置一次,隨時運行;隨地部署,集中化管理;開源。
    目前,多數項目會有多數據源要求,或者是主從部署要求,所以我們還需要引入mybatis-plus關于多數據源依賴:。#設置默認數據源或者數據源組,默認值即為master. true未匹配指定數據源時拋異常,false使用默認數據源。表名注解,用于標識實體類對應表。其說明如下,關于這些書寫,常規情況基本很少用到,不做多余解釋了:@Documented
    MyBatis-Plus是一個 MyBatis 增強工具,在 MyBatis 基礎上只做增強不做改變,為簡化開發、提高效率而生。真實開發中,version(樂觀鎖),deleted、gmt_create、gem_mo
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类