事件流和事件溯源是事件驅動架構中兩個相關但不同的概念。
事件流是將系統中發生的事件持續捕捉和記錄的過程。這些事件可以立即處理和分析,也可以被儲存以備後續分析。事件流通常應用於需要處理大量即時數據的系統,如金融交易或社交媒體平台。
以下是使用流行的Kafka訊息系統在Go中進行事件流處理的簡單範例:
package main import ( "context" "fmt" "github.com/segmentio/kafka-go" ) func main() { // 设置Kafka生产者以将事件发送到主题 writer := kafka.NewWriter(kafka.WriterConfig{ Brokers: []string{"localhost:9092"}, Topic: "my-topic", }) // 发送一些事件到主题 writer.WriteMessages(context.Background(), kafka.Message{ Key: []byte("key1"), Value: []byte("value1"), }, kafka.Message{ Key: []byte("key2"), Value: []byte("value2"), }, ) // 设置Kafka消费者以从主题读取事件 reader := kafka.NewReader(kafka.ReaderConfig{ Brokers: []string{"localhost:9092"}, Topic: "my-topic", }) // 从主题读取事件 for { msg, err := reader.ReadMessage(context.Background()) if err != nil { break } fmt.Printf("Received message: key=%s, value=%sn", string(msg.Key), string(msg.Value)) } }
而事件溯源是一種建構系統的模式,將應用程式狀態的所有變化儲存為事件序列。然後這些事件可以用於在任何時間點重建應用程式的狀態。事件溯源通常用於需要可審計性、可追溯性或合規性的系統,如金融系統或醫療系統。
以下是在Go中使用記憶體事件儲存進行事件溯源的簡單範例:
package main import ( "fmt" ) type Event struct { Type string Data interface{} } type EventStore struct { events []Event } func (store *EventStore) Append(event Event) { store.events = append(store.events, event) } func (store *EventStore) GetEvents() []Event { return store.events } type Account struct { idstring balance int store *EventStore } func NewAccount(id string, store *EventStore) *Account { return &Account{ id:id, balance: 0, store: store, } } func (account *Account) Deposit(amount int) { event := Event{ Type: "deposit", Data: amount, } account.store.Append(event) account.balance += amount } func (account *Account) Withdraw(amount int) { if account.balance >= amount { event := Event{ Type: "withdraw", Data: amount, } account.store.Append(event) account.balance -= amount } } func (account *Account) GetBalance() int { return account.balance } func main() { store := &EventStore{} account := NewAccount("123", store) account.Deposit(100) account.Withdraw(50) account.Deposit(25) events := store.GetEvents() for _, event := range events { switch event.Type { case "deposit": amount := event.Data.(int) fmt.Printf("Deposited %dn", amount) case "withdraw": amount := event.Data.(int) fmt.Printf("Withdrew %dn", amount) } } fmt.Printf("Final balance: %dn", account.GetBalance()) }
事件溯源是透過將每個對聚合的修改記錄為事件並將其追加到連續流中的一種方法。要重建聚合的最終狀態,需要依序讀取這些事件,然後將其套用於聚合。這與在建立、讀取、更新和刪除(CRUD)系統中執行的即時修改形成對比。在CRUD系統中,對記錄狀態的任何變更都儲存在資料庫中,實質上覆蓋了同
一聚合的先前版本。
價格變動已儲存到Products表中後,只有價格會被更新,而其他部分將保持不變。然而,這種方法可能導致遺失先前價格和變更背後的上下文,如圖5.1所示。
為了保留包括新價格和關鍵元資料(如調整原因)在內的信息,更改記錄將儲存在Events表中作為事件。先前的價格將保持不變,以確保在必要時可以進行檢索。
為了實現有效的事件溯源,建議使用提供強大一致性保證並使用樂觀並發控制的事件儲存。在實踐中,這意味著當多個修改同時發生時,只有初始修改才能附加到流中。隨後的修改可能需要重試或可能失敗。
以上是事件流與事件溯源的詳細內容。更多資訊請關注PHP中文網其他相關文章!