Newbe.Claptrap 框架中 State 和 Event 應該如何理解?最近整理了一下專案的術語表。今天就談談什麼是 Event 和 State。
Newbe.Claptrap 是一個用於輕鬆應對併發問題的分散式開發框架。如果您是首次閱讀本系列文章。建議可以先從本文末尾的入門文章開始瞭解。
事件 Event
Claptrap 是基於事件溯源的 Actor 模式。事件自然就起到了至關重要的作用。
想要操作 Claptrap 就需要對其傳遞事件。事件也是改變 Claptrap State 的唯一引數。因此,在使用 Claptrap 構建系統時,所有的系統操作都會轉換為事件而傳入到 Claptrap 中。事件具有以下這些特點:
事件是有序的
每個事件都包含有一個唯一的序列號。在本框架中,這個序列號被稱為版本號(Version)。事件的版本號是一個從 1 開始逐 1 遞增的序列。事件的有序性,確保了狀態的計算不存在併發問題。這是狀態資料可靠性的重要保證。
事件的有序性直接反應了 Claptrap 執行事件的先後順序。而由於需要確保這種順序,Claptrap 在執行事件時,必須逐個事件進行處理。這點恰好與 Actor 模式的單執行緒特性產生了天然的契合。
事件是不可變的
事件一旦產生,它就是不可變的。事件溯源,正由於事件的不可變性,才使得資料是可靠的。因為只要讀取事件,就能夠還原出任何一個事件執行之後的狀態。但不可變性並不是物理上的限制。你仍然可以修改物理儲存中的事件資料。但請注意,這是危險的,極為不建議的行為。
讓我們聯絡設計模式中的 “開閉原則”,經典的可以被概括為 “對擴充套件開放,對修改封閉”。其中為什麼要強調 “對修改封閉” 呢?就筆者看來,對修改封閉的原因其實是因為修改所帶來的未知性。因為過往執行的程式碼,產生的資料。他們都已經形成了一定的封閉性。他們是經過已有的測試所驗證的。如果嘗試修改他們,勢必就需要調整相應的測試,而這就更進一步加劇了修改,這可不是一件好事。事件的不可變是一種性質,更是一種要求。
那如果由於一個 BUG 導致了過往的產生事件資料不正確,現在需要修正這個 BUG,該怎麼辦呢?筆者的建議,不要嘗試修改已有的事件。應該追加新的事件和演算法來修正當前的狀態。不要去調整舊的內容。筆者認為這更符合開閉原則。開發者可以自行斟酌。
事件是永久的
事件是確保 Claptrap State 正確性的重要引數。因此,需要確保事件被永久儲存。但,這不是絕對的情況,如果滿足以下條件,那麼事件就允許被丟失:
- 在丟失事件之前存在一個永久的 State 快照
- 對應的 Claptrap 已經生命終結,永遠都不會再被啟用
反之,如果不滿足以上的條件,那麼請必須確保在生產環境中的事件被正確的儲存在持久化層,並且已經有相應的容災手段。
狀態 State
State 在 Actor 模式中代表了 Actor 物件當前的資料表現。而在 Claptrap 僅僅只是在此之上增加了一個限制:“State 只能通過事件溯源的方式進行更新”。由於事件溯源的可靠性。Claptrap 中的 State 也就擁有了更好的可靠性。
State 的版本號。在 Claptrap 中的 State 中有一個名為 Version 的屬性,它表示 State 當前的版本。版本號是一個從 0 開始的自增數字,會在每次處理一個事件之後進行自增。
版本號為 0 的 State 是 Claptrap 的初始狀態,也可以被稱為創世狀態。初始狀態可以根據業務需要進行定製。
Claptrap 和 Minion 對於版本號的處理也有一些區別。
對於 Claptrap 而言,Claptrap 是事件的生產者,因此,事件的版本號本身就是由 Claptrap 進行賦予的。例如,在一次事件的處理過程中,以下這些事情將會依次發生:
- State Version = 1000
- 開始處理 Event ,其 Version = State Version + 1 = 1001
- Event 處理完畢,更新 State Version = 1001
對於 Minion 而言,由於它是 Claptrap 事件的消費者。因此版本號的處理略有不同。例如,在一次事件的處理過程中,以下事件將會依次發生:
- State Version = 1000
- 讀取到了 Event Version 為 1001 的事件
- Event 處理完畢,更新 State Version = 1001
State 的版本號和 Event 的版本號相互依存,相互驗證,是事件有序性的關鍵。如果在處理過程中,出現 State 的版本號和 Event 的版本號不匹配的情況,將會是嚴重的問題。通常來說,出現版本號不匹配,只有兩種情況:
- 持久化層中的事件出現了丟失
- 框架惡性 BUG
最後但是最重要!
最近作者正在構建以反應式
、Actor模式
和事件溯源
為理論基礎的一套服務端開發框架。希望為開發者提供能夠便於開發出 “分散式”、“可水平擴充套件”、“可測試性高” 的應用系統 ——Newbe.Claptrap
本篇文章是該框架的一篇技術選文,屬於技術構成的一部分。如果讀者對該內容感興趣,歡迎轉發、評論、收藏文章以及專案。您的支援是促進專案成功的關鍵。
聯絡方式:
- Github Issue
- Gitee Issue
- 公開郵箱 newbe-claptrap@googlegroups.com (傳送到該郵箱的內容將被公開)
- Gitter
- QQ 群 553474855
您還可以查閱本系列的其他選文:
理論入門篇
- Newbe.Claptrap - 一套以 “事件溯源” 和 “Actor 模式” 作為基本理論的服務端開發框架
- Newbe.Claptrap 專案週報 1 - 還沒輪影,先用輪跑
- Newbe.Claptrap 框架中為什麼用 Claptrap 和 Minion 兩個詞?
實現入門篇
樣例實踐篇
其他番外篇
- 談反應式程式設計在服務端中的應用,資料庫操作優化,從 20 秒到 0.5 秒
- 談反應式程式設計在服務端中的應用,資料庫操作優化,提速 Upsert
- 十萬同時線上使用者,需要多少記憶體?——Newbe.Claptrap 框架水平擴充套件實驗
- docker-mcr 助您全速下載 dotnet 映象
術語介紹篇
GitHub 專案地址:https://github.com/newbe36524/Newbe.Claptrap
Gitee 專案地址:https://gitee.com/yks/Newbe.Claptrap
您當前檢視的是先行釋出於 www.newbe.pro 上的部落格文章,實際開發文件隨版本而迭代。若要檢視最新的開發文件,需要移步 claptrap.newbe.pro。
- 本文作者: newbe36524
- 本文連結: https://www.newbe.pro/Newbe.Claptrap/Event-And-State/
- 版權宣告: 本部落格所有文章除特別宣告外,均採用 BY-NC-SA 許可協議。轉載請註明出處!