參數(shù)解析器
你可以配置額外的ParameterResolvers扛拨,通過(guò)擴(kuò)展ParameterResolverFactory類和創(chuàng)建一個(gè)名為/META-INF/service/org.axonframework.common.annotation.ParameterResolverFactory的文件委粉,包含實(shí)現(xiàn)類的完全限定名稱靠娱。
警告
此時(shí)饰抒,OSGi支持僅限于在清單文件中被提到的所需的頭這一事實(shí)蔫慧。ParameterResolverFactory實(shí)例的自動(dòng)檢測(cè)在OSGi上工作,但由于類加載器的局限性备埃,它可能需要復(fù)制/META-INF/service/org.axonframework.common.annotation.ParameterResolverFactory 文件的內(nèi)容到OSGi包节槐,包含用于解析參數(shù)的類(即事件處理程序)。
Meta Annotations
TODO
Customizing Message Handler behavior
TODO
性能調(diào)優(yōu)
待辦事項(xiàng):更新Axon3
本章包含一個(gè)清單和在為生產(chǎn)級(jí)性能做準(zhǔn)備時(shí)需要考慮的一些指導(dǎo)方針【庖牵現(xiàn)在泵督,你可能已經(jīng)使用了測(cè)試固件測(cè)試你的命令處理邏輯和sagas。然而庶喜,生產(chǎn)環(huán)境不像測(cè)試環(huán)境那么寬容小腊。聚合往往存活得更久,更頻繁地和并發(fā)的使用久窟。對(duì)于額外的性能和穩(wěn)定性秩冈,你最好調(diào)整配置滿足你的具體需求。
數(shù)據(jù)庫(kù)索引和列類型
SQL DatabasesSQL數(shù)據(jù)庫(kù)
如果你使用你的JPA實(shí)現(xiàn)自動(dòng)生成表(例如Hibernate)瘸羡,你可能沒(méi)有把所有正確的索引設(shè)置在你的表上。為獲得最佳性能搓茬,事件存儲(chǔ)的不同用法需要不同的索引設(shè)置犹赖。該列表顯示,為默認(rèn)EventStorageEngine實(shí)現(xiàn)使用的不同類型的查詢添加不同類型的索引:
- 標(biāo)準(zhǔn)操作使用(存儲(chǔ)和加載事件):
Table 'DomainEventEntry', columns aggregateIdentifier and sequenceNumber (unique index)
Table 'DomainEventEntry', eventIdentifier (unique index) - 快照:
Table 'SnapshotEventEntry', aggregateIdentifier column.
Table 'SnapshotEventEntry', eventIdentifier (unique index) - Sagas
Table 'AssociationValueEntry', columns associationKey and sagaId,
默認(rèn)生成的列長(zhǎng)度可以工作卷仑,例如Hibernate峻村,但不會(huì)是最優(yōu)的。例如锡凝,一個(gè)UUID總是有相同的長(zhǎng)度粘昨。而不是可變長(zhǎng)度列255個(gè)字符,你可以為聚合標(biāo)識(shí)符使用一個(gè)固定長(zhǎng)度36個(gè)字符的列。
“時(shí)間戳”列在DomainEventEntry表只儲(chǔ)存ISO 8601時(shí)間戳张肾。如果所有時(shí)間存儲(chǔ)在UTC時(shí)區(qū)芭析,他們需要一個(gè)長(zhǎng)度為24個(gè)字符的列。如果你使用另一個(gè)時(shí)區(qū)吞瞪,這可能高達(dá)28位馁启。使用可變長(zhǎng)度列通常是沒(méi)有必要的,因?yàn)闀r(shí)間戳總是具有相同的長(zhǎng)度芍秆。
警告
強(qiáng)烈建議所有時(shí)間戳以UTC格式存儲(chǔ)惯疙。在夏令時(shí)的國(guó)家,用當(dāng)?shù)貢r(shí)間存儲(chǔ)時(shí)間戳妖啥,在時(shí)區(qū)轉(zhuǎn)換時(shí)可能會(huì)導(dǎo)致事件生成的順序錯(cuò)誤霉颠。使用UTC時(shí)不會(huì)發(fā)生這種情況。有些服務(wù)器配置為始終使用UTC荆虱。另外你應(yīng)該在存儲(chǔ)它們之前配置事件存儲(chǔ)將時(shí)間戳轉(zhuǎn)換成UTC蒿偎。
在DomainEventEntry中的“type”列存儲(chǔ)聚合的標(biāo)識(shí)符類型。一般來(lái)說(shuō)克伊,這些都是聚合的簡(jiǎn)單的名稱酥郭。在Spring中事件臭名昭著的“AbstractDependencyInjectionSpringContextTests”只算45個(gè)字符。在這里愿吹,再一次不从,一個(gè)長(zhǎng)度較短(但可變)的字段應(yīng)該足夠了。
MongoDB
默認(rèn)情況下犁跪,MongoEventStore只會(huì)為正確的操作生成它需要的索引椿息。這意味著當(dāng)事件存儲(chǔ)被創(chuàng)建時(shí),所需的惟一索引在“聚合標(biāo)識(shí)符”坷衍、“聚合類型”和“事件序列號(hào)”上也被創(chuàng)建寝优。然而,當(dāng)為某些操作使用MongoEventStore時(shí)枫耳,可能是值得添加一些額外索引的乏矾。
注意,在查詢優(yōu)化和更新速度之間的總有一個(gè)平衡點(diǎn)迁杨。負(fù)載測(cè)試最終是發(fā)現(xiàn)哪些索引提供最佳性能的最好方法钻心。
- 正常操作使用:
在“aggregateIdentifier”上自動(dòng)創(chuàng)建一個(gè)索引,“type”和“sequenceNumber”在領(lǐng)域事件(缺省名稱:“domainevents”)集合中铅协。 - Snapshotting:
在事件快照(缺省名稱:“snapshotevents”)集合中把(unique)索引放“aggregateIdentifier”,“type”和“sequenceNumber“上捷沸。 - Replaying events:
在領(lǐng)域事件(缺省名稱:“domainevents”)集合中,把非唯一索引放在“timestamp”和“sequenceNumber”上狐史。 - Sagas:
在saga(默認(rèn)名稱:“sagas”)集合中把(唯一)索引放到“sagaIdentifier”上痒给。
在saga(默認(rèn)名稱:“sagas”)集合中把索引放到”sagaType”说墨、“associations.key”和“associations.value“屬性上。
Caching
一個(gè)設(shè)計(jì)良好的命令處理模塊當(dāng)實(shí)現(xiàn)緩存時(shí)應(yīng)該不會(huì)構(gòu)成任何問(wèn)題苍柏。尤其是當(dāng)使用事件溯源時(shí)尼斧,從事件存儲(chǔ)中加載一個(gè)聚合是一項(xiàng)昂貴的操作。用正確配置的緩存序仙,加載一個(gè)聚合可以轉(zhuǎn)化為一個(gè)純粹的in-memory過(guò)程突颊。
下面是一些幫助您最大限度地利用緩存解決方案的指導(dǎo)原則:
確保工作單元永遠(yuǎn)不需要為功能原因執(zhí)行回滾。
回滾意味著一個(gè)聚合已經(jīng)達(dá)到了一個(gè)無(wú)效的狀態(tài)潘悼。Axon會(huì)自動(dòng)將相關(guān)的緩存項(xiàng)失效律秃。下一個(gè)請(qǐng)求將迫使聚合從事件中重建。如果你使用異常作為一個(gè)潛在的(功能的)返回值治唤,你可以在命令總線上配置一個(gè)RollbackConfiguration棒动。默認(rèn)情況下,當(dāng)運(yùn)行時(shí)異常時(shí)這個(gè)工作單元將回滾宾添。單個(gè)聚合的所有命令必須到達(dá)在緩存中具有該聚合的機(jī)器上船惨。
這意味著命令應(yīng)該始終被路由到同一臺(tái)機(jī)器,只要這臺(tái)機(jī)器是“健康”的缕陕。路由命令總是阻止緩存過(guò)期粱锐。命中一個(gè)過(guò)期緩存將導(dǎo)致一個(gè)命令被執(zhí)行,并且事件存儲(chǔ)在事件存儲(chǔ)中會(huì)失敗扛邑。配置一個(gè)合理的生存時(shí)間/閑置時(shí)間
默認(rèn)情況下怜浅,緩存傾向于有一個(gè)相對(duì)較短的生存時(shí)間,即幾分鐘蔬崩。對(duì)于具有一致的路由的命令處理組件恶座,一個(gè)較長(zhǎng)的閑置時(shí)間和生存時(shí)間通常是更好的。這可以防止需要初始化一個(gè)基于它的事件的聚合沥阳,僅僅因?yàn)樗木彺鏃l目過(guò)期了跨琳。緩存的生存時(shí)間應(yīng)該與你的聚合的預(yù)期壽命相匹配。
Snapshotting
快照刪除需要重載和重放大量的事件桐罕。單個(gè)快照代表在在某一特定時(shí)刻整個(gè)聚合狀態(tài)脉让。然而,快照的處理本身也需要處理時(shí)間功炮。因此溅潜,在構(gòu)建快照時(shí)所花費(fèi)的時(shí)間和阻止許多事件被讀取節(jié)省的時(shí)間應(yīng)該保持平衡。
對(duì)所有類型的應(yīng)用程序都沒(méi)有默認(rèn)行為死宣。一些將指定一些事件之后將創(chuàng)建一個(gè)快照伟恶,而其他應(yīng)用程序需要一個(gè)基于時(shí)間的快照間隔碴开。無(wú)論你選擇何種方式為您的應(yīng)用程序毅该,如果你有l(wèi)ong-living聚合博秫,確保快照就位眶掌。