24.Axon框架-事件(二)

Axon框架-事件(二)

1.什么是事件处理器

2.明确概念

  • EventProcessor:事件处理器
  • ProcessingGroup:处理组
  • EventHandler:事件处理程序

3.事件处理器分层结构

介绍

  1. 事件处理程序(EventHandler):接收事件时需执行的业务逻辑
  2. 事件处理器(EventProcessor):则是负责处理事件处理过程中技术层面工作的组件。它会启动一个工作单元,可能还会开启事务;此外,它还需确保事件处理期间创建的所有消息能正确附加关联数据,同时满足其他非功能需求(如性能、容错等)
  3. 处理组(Processing Group):每个EventHandler仅属于一个处理组。处理组为事件处理提供了可配置的非功能需求能力,例如错误处理、排序策略等

为EventHandler分配ProcessingGroup

介绍

所有EventProcessor都有一个名称,该名称在多个JVM实例间唯一标识一个EventProcessor实例,两个名称相同的EventProcessor会被视为同一EventProcessor的不同实例

所有EventHandler默认会附加到名称为其类所在包名的事件处理器上。此外,Axon默认使用的EventProcessor实现是TrackingEventProcessor(跟踪式事件处理器)

EventHandler大致分为两类:常规EventHandler,Saga的EventHandler,这里介绍常规EventHandler的流程

两种分配方式

更精细的分配方式

介绍

Axon的配置API允许自定义的更精细的分配方式,这些规则可分为两大类:

  • EventHandler → ProcessingGroup
  • ProcessingGroup → EventProcessor
事件处理程序到处理组
  1. byDefaultAssignTo(String):定义EventHandler的默认ProcessingGroup名称。仅在无更具体规则且未标注@ProcessingGroup注解时生效
  2. byDefaultAssignHandlerInstancesTo(Function<Object, String>):通过Lambda表达式为EventHandler实例分配ProcessingGroup(返回ProcessingGroup名称)。仅在无更具体规则且未标注@ProcessingGroup注解时生效
  3. byDefaultAssignHandlerTypesTo(Function<Class<?>, String>):通过Lambda表达式为EventHandler类型分配ProcessingGroup(返回ProcessingGroup名称)。仅在无更具体规则且未标注@ProcessingGroup注解时生效
  4. assignHandlerInstancesMatching(String, Predicate<Object>):根据EventHandler实例是否匹配Predicate条件,将其分配到指定ProcessingGroup。默认优先级为0;若一个实例匹配多个条件,结果未定义
  5. assignHandlerTypesMatching(String, Predicate<Class<?>>):根据EventHandler类型是否匹配Predicate条件,将其分配到指定ProcessingGroup。默认优先级为0;若一个类型匹配多个条件,结果未定义
  6. assignHandlerInstancesMatching(String, int, Predicate<Object>):功能与第4点类似,但可自定义优先级(数值越高,规则优先级越高)
  7. assignHandlerTypesMatching(String, int, Predicate<Class<?>>):功能与第5点类似,但可自定义优先级(数值越高,规则优先级越高)
处理组到事件处理器
  1. assignProcessingGroup(String, String):将指定名称的ProcessingGroup,分配给指定名称的EventProcessor
  2. assignProcessingGroup(Function<String, String>):通过Lambda表达式为ProcessingGroup分配EventProcessor(输入ProcessingGroup,名称,返回EventProcessor名称)

EventProcessor内部的EventHandler顺序问题

介绍

默认顺序就是它们在配置API中的注册顺序一致

Spring环境下的显式排序

若使用Spring进行依赖注入,可通过@Order注解显式指定事件处理程序的排序。该注解标注在事件处理程序类上,通过整数参数指定优先级(数值越小,优先级越高)

java 复制代码
@ProcessingGroup("my-handlers")
@Order(1) // 优先级高于 @Order(2) 的组件
public class HighPriorityHandler {
    @EventHandler
    public void on(ImportantEvent event) {
        // 高优先级逻辑
    }
}

@ProcessingGroup("my-handlers")
@Order(2) // 优先级低于 @Order(1) 的组件
public class LowPriorityHandler {
    @EventHandler
    public void on(ImportantEvent event) {
        // 低优先级逻辑(在 HighPriorityHandler 之后执行)
    }
}
注意事项

4.事件错误处理

介绍

ProcessingGroup层级(ListenerInvocationErrorHandler)

介绍

ListenerInvocationErrorHandler负责处理事件处理程序方法抛出的异常。默认实现为LoggingErrorHandler,记录异常日志后,继续处理下一个处理程序或事件

原生API配置
java 复制代码
public class AxonConfig {
    // 省略其他配置方法...
    public void configureProcessingGroupErrorHandling(EventProcessingConfigurer processingConfigurer) {
        // 1. 配置所有处理组的默认错误处理器
        processingConfigurer
            .registerDefaultListenerInvocationErrorHandler(conf -> {
                // 示例:返回自定义 ListenerInvocationErrorHandler 实例
                return (exception, event, eventHandler) -> {
                    // 自定义逻辑:如重试、忽略、死信队列投递等
                    log.error("EventHandler [{}] failed to process event [{}]", 
                              eventHandler.getClass().getSimpleName(), 
                              event.getPayloadType().getSimpleName(), 
                              exception);
                    // 若需向上传播异常,直接抛出即可
                    // throw new RuntimeException("Propagate error", exception);
                };
            })
            // 2. 为特定处理组配置专属错误处理器
            .registerListenerInvocationErrorHandler("my-processing-group", conf -> {
                // 为 "my-processing-group" 处理组配置自定义错误处理器
                return new CustomMyGroupErrorHandler();
            });
    }
}
SpringBoot配置
java 复制代码
@Configuration
public class AxonConfig {
    // 省略其他配置方法...
    @Bean
    public ConfigurerModule processingGroupErrorHandlingConfigurerModule() {
        return configurer -> configurer.eventProcessing(processingConfigurer ->
            processingConfigurer
                // 配置默认错误处理器
                .registerDefaultListenerInvocationErrorHandler(conf -> {
                    return new LoggingErrorHandler(); // 也可使用自定义实现
                })
                // 为特定处理组配置错误处理器
                .registerListenerInvocationErrorHandler(
                        "my-processing-group",
                        conf -> new CustomMyGroupErrorHandler()
                )
        );
    }
}
自定义ListenerInvocationErrorHandler

实现ListenerInvocationErrorHandler接口即可自定义错误处理逻辑,接口提供以下参数:

java 复制代码
public interface ListenerInvocationErrorHandler {
    void onError(Exception exception,
                 EventMessage<?> event,
                 EventMessageHandler eventHandler) throws Exception;
}
  1. exception:EventHandler抛出的异常
  2. event:待处理的事件
  3. eventHandler:抛出异常的EventHandler

可根据需求选择重试忽略或向上传播异常;若向上传播,异常会进入EventProcessor

EventProcessor层级(ErrorHandler)

介绍

EventHandler方法外抛出的异常或从EventHandler层级传播上来的异常,由ErrorHandler处理。默认实现为PropagatingErrorHandler,直接重新抛出所有捕获的异常

不同事件处理器类型的异常传播行为
  1. 订阅式事件处理器(SubscribingEventProcessor):异常会传播给事件发布者
  2. 流处理式事件处理器(StreamingEventProcessor):进入错误模式,重试失败后暂停处理
原生API配置
java 复制代码
public class AxonConfig {
    public void configure(EventProcessingConfigurer configurer) {
        configurer
            // 1. 配置所有事件处理器的默认错误处理器
            .registerDefaultErrorHandler(conf -> {
                // 示例:自定义 ErrorHandler,支持重试
                return new RetryingErrorHandler(
                        IntervalRetryScheduler.builder()
                                             .retryCount(3)
                                             .interval(Duration.ofSeconds(1))
                                             .build()
                );
            })
            // 2. 为特定事件处理器配置专属错误处理器
            .registerErrorHandler("my-processor", conf -> {
                return new CustomProcessorErrorHandler();
            });
    }
}
SpringBoot配置
java 复制代码
@Configuration
public class AxonConfig {
    @Bean
    public ConfigurerModule processorErrorHandlingConfigurerModule() {
        return configurer -> configurer.eventProcessing(processing ->
            processing
                // 配置全局默认错误处理器
                .registerDefaultErrorHandler(conf -> new RetryingErrorHandler())
                // 为特定事件处理器配置错误处理器
                .registerErrorHandler("my-processor", conf -> new CustomProcessorErrorHandler())
        );
    }
}
自定义ErrorHandler

实现ErrorHandler接口,通过ErrorContext获取错误上下文信息,自定义处理逻辑(如忽略、重试、死信队列投递等):

java 复制代码
public interface ErrorHandler {
    void handleError(ErrorContext errorContext) throws Exception;
}

// 示例:自定义 ErrorHandler
public class CustomErrorHandler implements ErrorHandler {
    @Override
    public void handleError(ErrorContext errorContext) throws Exception {
        Exception cause = errorContext.getCause();
        EventMessage<?> event = errorContext.getEvent();
        // 自定义逻辑:如判断异常类型,决定是否投递到死信队列
        if (cause instanceof NonTransientException) {
            // 非暂时性异常:投递到死信队列
            deadLetterQueue.send(event, cause);
        } else {
            // 暂时性异常:重试
            throw cause; // 向上传播,触发重试
        }
    }
}

死信队列

这一部分内容,还专门有一章,这里理解为一个持续失败的事件会产生不好的影响,需要死信队列来参与解决

5.EventProcessor通用配置

介绍

除了处理EventHandler分配和错误处理,EventProcessor还支持其他组件的配置。订阅式和流处理式事件处理器的专属配置以后说,这里是通用配置

EventProcessorBuilder

介绍

EventProcessingConfigurer提供了大量EventProcessor的可配置组件,但有时直接提供构建EventProcessor的完整逻辑会更便捷。此时可通过EventProcessorBuilder自定义构建逻辑

配置方式

EventProcessingConfigurer提供两种配置EventProcessorBuilder的方法:

  1. registerEventProcessorFactory(EventProcessorBuilder):为未配置专属构建器的EventProcessor,配置默认构建工厂
  2. registerEventProcessor(String, EventProcessorBuilder):为指定名称的EventProcessor,配置专属构建器
java 复制代码
public class AxonConfig {
    public void configureEventProcessorBuilder(EventProcessingConfigurer processingConfigurer) {
        // 1. 配置默认构建器:所有未指定专属构建器的处理器使用此逻辑
        processingConfigurer.registerEventProcessorFactory((name, config, invoker) -> {
            // 示例:根据处理器名称,选择构建 Subscribing 或 Tracking 处理器
            if (name.startsWith("subscribing-")) {
                return SubscribingEventProcessor.builder()
                                                .name(name)
                                                .eventHandlerInvoker(invoker)
                                                .messageSource(config.eventBus())
                                                .build();
            } else {
                return TrackingEventProcessor.builder()
                                             .name(name)
                                             .eventHandlerInvoker(invoker)
                                             .tokenStore(config.tokenStore())
                                             .build();
            }
        });

        // 2. 为 "custom-processor" 配置专属构建器
        processingConfigurer.registerEventProcessor("custom-processor", 
            (name, config, invoker) -> new CustomEventProcessor(name, invoker, config.eventStore())
        );
    }
}

EventHandler拦截器

介绍

EventProcessor是EventHandler的调用者,因此也是配置EventHandler拦截器的合适位置。由于EventProcessor专门处理事件,此处的拦截器需针对EventMessage,即EventHandlerInterceptor

配置方式

EventProcessingConfigurer提供两种配置拦截器的方法:

  1. registerDefaultHandlerInterceptor(BiFunction<Configuration, String, MessageHandlerInterceptor<? super EventMessage<?>>>):为所有EventProcessor配置默认拦截器(输入全局配置和EventProcessor名称,返回拦截器实例)
  2. registerHandlerInterceptor(String, Function<Configuration, MessageHandlerInterceptor<? super EventMessage<?>>>):为指定名称的EventProcessor配置专属拦截器
java 复制代码
public class AxonConfig {
    public void configureInterceptors(EventProcessingConfigurer processingConfigurer) {
        // 1. 配置全局默认拦截器:为所有处理器添加关联数据拦截
        processingConfigurer.registerDefaultHandlerInterceptor((config, processorName) -> 
            new CorrelationDataInterceptor<>(config.correlationDataProviders())
        );

        // 2. 为 "audit-processor" 配置专属审计拦截器
        processingConfigurer.registerHandlerInterceptor("audit-processor", config -> 
            new AuditLoggingInterceptor() // 自定义审计拦截器,记录事件处理日志
        );
    }
}

消息监控

介绍

所有EventProcessor实例都支持配置MessageMonitor。MessageMonitor用于监控Axon应用中消息的流转过程,对于EvnetProcessor而言,它会专门监控从EventProcessor流向EventHandler的事件

配置方式

MessageMonitorFactory是Axon配置API中通用的监控器构建接口,支持更灵活的监控器创建逻辑:

java 复制代码
@FunctionalInterface
public interface MessageMonitorFactory {
    // 参数说明:
    // - configuration:全局配置(可获取依赖组件)
    // - componentType:组件类型(事件处理器场景下为 EventProcessor 实现类)
    // - componentName:组件名称(事件处理器名称)
    MessageMonitor<Message<?>> create(Configuration configuration,
                                      Class<?> componentType,
                                      String componentName);
}

示例:

java 复制代码
public class AxonConfig {
    public void configureMessageMonitor(EventProcessingConfigurer processingConfigurer) {
        // 使用工厂为 "metrics-processor" 配置监控器
        processingConfigurer.registerMessageMonitorFactory("metrics-processor", 
            (config, componentType, componentName) -> {
                // 示例:基于 Micrometer 实现事件处理指标监控
                return MicrometerMessageMonitor.builder(componentName)
                                              .meterRegistry(config.getComponent(MeterRegistry.class))
                                              .build();
            }
        );
    }
}

事务管理

介绍

EventProcessor负责事件处理,因此也是配置事务的合理位置。大多数场景下,默认配置已足够,本节仅介绍可调整的选项

TransactionManager

Axon使用TransactionManager为每个工作单元附加事务:

  1. Spring环境:默认使用SpringTransactionManager,底层依赖Spring的PlatformTransactionManager
  2. 非Spring环境:若需事务管理,需自定义TransactionManager实现,仅需实现TransactionManager#startTransaction()方法
配置方式

通过EventProcessingConfigurer的registerTransactionManager方法配置:

java 复制代码
public class AxonConfig {
    public void configureTransactionManager(EventProcessingConfigurer processingConfigurer) {
        // 为 "transactional-processor" 配置自定义事务管理器
        processingConfigurer.registerTransactionManager("transactional-processor", 
            config -> new CustomTransactionManager()
        );
    }
}
回滚配置

RollbackConfiguration用于决定工作单元何时需要回滚事务。默认配置为任何Throwable都会触发回滚,其他可选配置可参考工作单元

通过EventProcessingConfigurer的registerRollbackConfiguration方法配置:

java 复制代码
public class AxonConfig {
    public void configureRollback(EventProcessingConfigurer processingConfigurer) {
        // 为 "custom-rollback-processor" 配置自定义回滚策略:仅 RuntimeException 触发回滚
        processingConfigurer.registerRollbackConfiguration("custom-rollback-processor", 
            config -> RollbackConfigurationType.ANY_RUNTIME_EXCEPTION
        );
    }
}
相关推荐
你才是臭弟弟1 天前
SpringBoot 集成MinIo(根据上传文件.后缀自动归类)
java·spring boot·后端
C澒1 天前
面单打印服务的监控检查事项
前端·后端·安全·运维开发·交通物流
鸣潮强于原神1 天前
TSMC chip_boundary宽度规则解析
后端
Code blocks1 天前
kingbase数据库集成Postgis扩展
数据库·后端
Elieal1 天前
JWT 登录校验机制:5 大核心类打造 Spring Boot 接口安全屏障
spring boot·后端·安全
czlczl200209251 天前
Spring Boot Filter :doFilter 与 doFilterInternal 的差异
java·spring boot·后端
码界奇点1 天前
基于Spring Boot和Activiti6的工作流OA系统设计与实现
java·spring boot·后端·车载系统·毕业设计·源代码管理
yangminlei1 天前
Spring Boot拦截器(Interceptor)与过滤器(Filter)深度解析:区别、实现与实战指南
java·spring boot·后端
草履虫建模1 天前
力扣算法分析 27.移除元素
java·开发语言·数据结构·后端·算法·leetcode·排序算法
czlczl200209251 天前
Spring Boot :彻底解决 HttpServletRequest 输入流只能读取一次的问题
java·spring boot·后端