使用Axon重播投射事件 - codecentric AG Blog
事件儲存是任何事件源應用程式的核心。它包含系統生命週期中發生的每個事件。這些事件包含應用程式中的每個狀態更改。EventSourcing通常與命令查詢責任隔離(CQRS)結合使用。對於Axon而言,這意味著可以在投影中實現單獨的讀取面。 通常,事件在兩個主要位置影響了軟體的當前狀態:聚合和投影。
事件處理器
如果您熟悉Axon,則可能知道處理器有兩種型別:訂閱事件處理器和跟蹤事件處理器。這些處理器之間的主要區別在於,訂閱事件處理器將自己訂閱事件源,並由釋出機制管理的執行緒呼叫。另一方面,跟蹤事件處理器使用它自己管理的執行緒從源中提取訊息。
投射
我們軟體的當前狀態是由聚合執行這些事件的結果。投影是基於這些事件的特定檢視,每個檢視都有其自己的目的。例如,如果您向新銀行註冊,則將在“ CustomerRegisteredEvent”行中發出事件。您可以想象一些投射對此事件感興趣。比如可以跟蹤已註冊到銀行的客戶的所有個人資訊的計劃,或者可以跟蹤客戶在填寫其所需的所有資訊方面所取得的進展的計劃。
但是,隨著時間的流逝,需求將發生變化,您將看到您希望更新結構和內容上的投射。這就是Axon重播的地方。重播是Axon框架支援的CQRS和EventSourcing的核心概念。
僅當您使用跟蹤事件處理器時,才可以在Axon中重播。
一旦指定了要重播的事件,Axon將:
- 在重置之前,使用提供的事件和令牌的值建立重播令牌
- 更新令牌儲存中的令牌
- 從該點開啟事件流
- 閱讀事件
- 在跟蹤事件處理器上以工作單元處理事件
Spring Rest API
如何發起重播?有多種方法可以做到這一點。從Axon 4開始,可以在Axon Server中重播,但這超出了本部落格文章的範圍。另一種方法是在某個時間點重置跟蹤事件處理器。此解決方案的一個警告是,您必須在重置之前手動停止跟蹤事件處理器。第三種選擇是,您可以手動更新令牌儲存中的跟蹤令牌以重新處理過去的事件,最後,我們的首選解決方案是使用Axon提供的Replay API。
我們在Spring中利用此Replay API建立了安全的Rest API。我們唯一需要提供的資訊是我們要重播的位置以及跟蹤事件處理器的名稱。在重置處理器之前,我們檢查了處理器是否實際上在此例項上執行,如果是,則通過程式碼將其關閉。最終,Axon建立了一個重設令牌,該令牌包含重置時令牌的值,並將其插入令牌儲存中。當我們重播所有事件時,Axon會將重播令牌轉換回跟蹤令牌,並從中斷處繼續執行。
為了讓我們對TrackingEventProcessorService的外觀有所瞭解:
@Service @Slf4j public class TrackingEventProcessorService { private final EventProcessingConfiguration eventProcessingConfiguration; public TrackingEventProcessorService( EventProcessingConfiguration eventProcessingConfiguration ) { this.eventProcessingConfiguration = eventProcessingConfiguration; } private TrackingEventProcessor getTrackingEventProcessor(String name) { return this.eventProcessingConfiguration .eventProcessor(name, TrackingEventProcessor.class) .orElseThrow(TrackingEventProcessorNotFoundException::new); } public boolean replay(String trackingEventProcessorName, Long index) { TrackingEventProcessor trackingEventProcessor = this.getTrackingEventProcessor(trackingEventProcessorName); if (!trackingEventProcessor.isRunning()) { this.logger .warn( "Tracking event processor {} is not running in current instance or not running at all", trackingEventProcessorName ); return false; } trackingEventProcessor.shutDown(); try { trackingEventProcessor.resetTokens(GapAwareTrackingToken.newInstance(index - 1, Collections.emptySortedSet())); } catch (UnableToClaimTokenException e) { // Ignore this exception and let the caller know setting the replay failed. this.logger.warn("Unable to claim token for trackingEventProcessor {} on id {}", trackingEventProcessorName, index - 1, e); return false; } finally { this.logger.info("Starting replay for trackingEventProcessor {} on id {}", trackingEventProcessorName, index - 1); trackingEventProcessor.start(); } return true; } } |
該服務將使用Axon配置來獲取跟蹤事件處理器並開始重播。
心得
使用重放管理一年以上後,我們希望將一些發現與大小分享。
事件重播中的障礙在跟蹤事件處理中,事件是在不同的執行緒中處理的,這使得錯誤處理更加複雜。我們的錯誤處理不正確,每當發生錯誤時,重播令牌就會卡住。令牌儲存中的令牌失去了所有者,我們不得不重新部署服務以讓Axon分配新的所有者。
重播API的粘性會話我們遇到了一種情況,我們在負載均衡器上使用了粘性會話,而跟蹤事件處理器未在我們路由到的例項上執行,因此未啟動重放過程。當您的例項達到負載平衡時,最好實現輪詢並重復呼叫。
重播批量。在談論重放時,處理速度(時間)是非常重要的因素。根據複雜性,要重播的事件數和投影的記憶體利用率,重播可能要花費幾分鐘到幾天的時間。為了優化您的重放功能,可以設定跟蹤事件處理器的批處理大小。要了解這如何使您的重放體驗受益,應該知道Axon處理事件時會發生什麼。對於每個批次,Axon都需要更新跟蹤令牌,如果您使用的是事務性儲存,它將開始並提交資料庫事務。如果您一次處理一個事件,這會帶來很多開銷,並且可能會受益於更大的批處理量。
舉個例子
事件重播執行狀況指標發生令牌處理器無法趕上新事件的情況。可能有多種原因,因為順序處理非常重要。您需要調整處理一個事件所需的時間。我們曾多次花一整天的時間來優化RDMS查詢,以使其達到最佳播放速度。理想情況下,一旦令牌在總修訂版上進行,對於更簡單的類似於CRUD的事件,處理單個後續事件的時間不應超過100毫秒。但是,這僅僅是一個粗略的估計。一個事件表可以輕鬆地包含數百萬個事件,如果想充分利用重播功能,則重播事件流將需要數小時而不是數天。可以記錄有關令牌位置和事件範圍之間差異的指標。
(banq注:其實利用Java 8 stream等流式概念可以方便重播事件資料)
相關文章
- 如何使用ParcelJS在Spring Boot應用程式中打包前端 - codecentric AG BlogJSSpring Boot前端
- 事件溯源:投影或投射模式 -Kacper Gunia事件模式
- GitHub - soooban/AxonDemo: 使用Axon/Spring Cloud實現事件溯源和CQRS案例GithubSpringCloud事件
- 談DDD與貧血領域模型:再次為失血模型辯護 -Codecentric AG部落格模型
- 說服您的CTO使用事件溯源 -Event Store Blog事件
- 如何在Python中使用Java類? - codecentricPythonJava
- axon框架創始人談微服務與事件驅動框架微服務事件
- 在Axon框架中揭開跟蹤事件處理器的神秘面紗框架事件
- Axon框架指南 - Baeldung框架
- (譯)使用Spring Boot和Axon實現CQRS&Event SourcingSpring Boot
- AG買分
- 基於Axon框架使用Kotlin編寫的ES銀行案例框架Kotlin
- AG介面申請
- Angular開發實踐(八): 使用ng-content進行元件內容投射Angular元件
- Spring IO 2019大會上Axon+Spring的事件驅動微服務和CQRS原始碼專案Spring事件微服務原始碼
- 視訊重播轉換器:Replay Converter MacMac
- ag-grid api方法API
- 如何技術對接接入AG介面API產品(AG介面除錯)API除錯
- First Blog
- GitHub BLOGGithub
- a new blog
- 使用 guiscrcpy 將你的安卓手機的螢幕投射到你的電腦GUI安卓
- Spring Boot 2.5.x能支援Java 17了 - codecentricSpring BootJava
- Ag-Grid React入門React
- 怎麼樣把手機螢幕投射到電腦
- 使用kubernetes的10個最常見錯誤 – pipetail BlogAI
- 雲棲blog
- blog1
- My first blog!
- 串列埠blog串列埠
- BLOG2
- blog-1
- My First Blog
- About My Blog
- Blog目錄
- CQRS架構和Axon框架入門實踐架構框架
- 事件代理如何使用?事件
- Laravel使用event事件Laravel事件