SagaEventBus支持Saga模式
文章插图
具体是怎么做呢?
[EventHandler(1, IsCancel = true)]public void CancelSendAwardByRegister(RegisterUserEvent @event){ _logger?.LogDebug("-----------{Account} 注册成功,发放奖励失败 {Message}-----------", @event.Account, "发放奖励补偿");}
当发送奖励出现异常时,则执行补偿机制 , 执行顺序为 (2 - 1) > 0 , 由于目前仅存在一个Order为1的Handler,则执行奖励补偿后退出但对于部分不需要执行失败但不需要执行回退的方法 , 我们可以修改 FailureLevels 确保不会因为当前方法的异常而导致执行补偿机制
[EventHandler(3, FailureLevels = FailureLevels.Ignore)]public void SendNoticeByRegister(RegisterUserEvent @event){ _logger?.LogDebug("-----------{Account} 注册成功 {Message}-----------", @event.Account, "发送邮件提示注册成功"); //todo: 编写发送注册通知等}源码解读EventHandler
- FailureLevels: 失败级别, 默认: Throw
- Throw:发生异常后 , 依次执行Order小于当前Handler的Order的取消动作,比如:Handler顺序为 1、2、3,CancelHandler为 1、2、3 , 如果执行 Handler3 异常,则依次执行 2、1
- ThrowAndCancel:发生异常后,依次执行Order小于等于当前Handler的Order的取消动作,比如:Handler顺序为 1、2、3 , CancelHandler为 1、2、3,如果执行 Handler3 异常,则依次执行 3、2、1
- Ignore:发生异常后,忽略当前异常(不执行取消动作),继续执行其他Handler
- Order: 执行顺序,默认: int.MaxValue,用于控制当前方法的执行顺序
- EnableRetry: 当Handler异常后是否启用重试, 默认: false
- RetryTimes: 重试次数,当出现异常后执行多少次重试, 需开启重试配置
- IsCancel: 是否是补偿机制,默认: false
- SupportRecursive: 是否支持递归 (嵌套), 默认: true
- 部分中间件仅在最外层被触发一次,像TransactionMiddleware 就是如此,但也有很多中间件是需要被多次执行的,比如ValidatorMiddleware,每次发布事件时都需要验证参数是否正确
- HandleAsync(TEvent @event, EventHandlerDelegate next): 处理程序,通过调用 next() 使得请求进入下一个Handler
- HandleAsync(TEvent @event): 提供事件的Handler
- CancelAsync(TEvent @event): 提供事件的补偿Handler
与EventHandler功能类似,提供基本的Handler以及补偿Handler , 推荐使用EventHandler的方式使用TransactionMiddleware提供事务中间件,当EventBus与UoW以及Masa提供的Repository来使用时,当存在待提交的数据时,会自动执行保存并提交,当出现异常后,会执行事务回滚,无需担心脏数据入库
性能测试与市面上使用较多的MeidatR作了对比,结果如下图所示:
BenchmarkDotNet=v0.13.1, OS=Windows 10.0.19043.1023 (21H1/May2021Update)11th Gen Intel Core i7-11700 2.50GHz, 1 CPU, 16 logical and 8 physical cores.NET SDK=7.0.100-preview.4.22252.9[Host] : .NET 6.0.6 (6.0.622.26707), X64 RyuJIT DEBUGJob-MHJZJL : .NET 6.0.6 (6.0.622.26707), X64 RyuJIT
Runtime=.NET 6.0 IterationCount=100 RunStrategy=ColdStart
MethodMeanErrorStdDevMedianMinMaxAddShoppingCartByEventBusAsync124.80 us346.93 us1,022.94 us8.650 us6.500 us10,202.4 usAddShoppingCartByMediatRAsync110.57 us306.47 us903.64 us7.500 us5.300 us9,000.1 us根据性能测试我们发现,EventBus与MediatR性能差距很小,但EventBus提供的功能却要强大的多
常见问题
- 按照文档操作 , 通过EventBus发布事件后,对应的Handler并没有执行 , 也没有发现错误?
var assemblies = new[]{ typeof(UserHandler).Assembly};builder.Services.AddEventBus(assemblies);
推荐阅读
- YC-Framework版本更新:V1.0.10
- 从 QFramework 重新开始
- reportportal 集成 robotframework 自动化执行及结果可视化
- MasaFramework -- 缓存入门与设计
- MasaFramework -- 缓存入门与规则配置
- MasaFramework -- 异常处理
- .Net Framework中的AppDomain.AssemblyResolve事件的常见用法、问题,以及解决办法