Axon编排式通信:@DisallowReplay与Subscribing模式失效问题求助
解决Axon Framework重启后EventHandler重复执行事件的问题
1. 实现事件处理的幂等性(最稳妥方案)
不管事件是否重播,确保AddToDeliveryListCommand不会重复生效是根本解决思路:
- 在配送服务端,给每个配送任务绑定唯一订单ID,处理
OrderPlacedEvent前先查询该订单是否已存在配送记录 - 示例代码:
@EventHandler public void handle(OrderPlacedEvent event) { // 先校验订单是否已有对应配送任务 if (deliveryRepository.existsByOrderId(event.getOrderId())) { return; // 已存在则直接返回,不重复发命令 } // 无记录则发送配送命令 commandGateway.send(new AddToDeliveryListCommand(event.getOrderId(), event.getAddress())); }
2. 配置Tracking Event Processor的持久化TokenStore
Axon默认用Tracking Event Processor(TEP),如果用内存版TokenStore,重启会丢失追踪位置导致从头消费,需要换成持久化实现:
- 在Spring Boot配置文件中指定持久化TokenStore:
# 用JPA实现Token持久化,也可换成mongodb等 axon.eventhandling.processors.default.token-store=jpa
- 配置后,TEP重启会从上次处理的事件位置继续,不会重复消费已处理过的事件
3. 修复@DisallowReplay注解失效问题
@DisallowReplay只对Axon识别的**投影类(Projection)**生效,需确保EventHandler所在类标记@Projection:
- 示例代码:
@Projection public class DeliveryProjection { @DisallowReplay @EventHandler public void handle(OrderPlacedEvent event) { commandGateway.send(new AddToDeliveryListCommand(...)); } }
- 注意:该注解需配合持久化TokenStore使用,才能彻底避免重启后的事件重播
4. 解决Subscribing模式无法接收事件的问题
Subscribing模式收不到事件通常是总线配置问题:
- 分布式场景下必须配置Axon Server作为事件总线,在配置文件中添加:
axon.axonserver.servers=你的AxonServer地址:8124
- 明确指定处理器为订阅模式:
axon.eventhandling.processors.default.mode=subscribing
5. 修复EventBus作为Source的Bean错误
出现Bean冲突时,需明确指定要注入的EventBus实现:
- 分布式场景下优先使用AxonServerEventBus,配置类示例:
@Configuration public class AxonConfig { @Bean public EventBus eventBus(AxonServerConnectionManager connectionManager) { return new AxonServerEventBus(connectionManager, new DefaultEventSerializer()); } }
- 直接依赖Axon Starter的话,框架会自动配置正确的EventBus实现,无需手动声明
内容的提问来源于stack exchange,提问作者장진영
相关产品推荐
相关产品推荐

