【微服务】02-集成事件与MediatR

文章目录

    • 1.集成事件
      • 1.1 定义
      • 1.2 集成事件工作原理
      • 1.3 总结
    • 2.使用RabbitMQ来实现EventBus
      • 2.1 RabbitMQ安装
      • 2.2 CAP框架实现RabbitMQ
        • 2.2.1 CAP框架实现架构
        • 2.2.2 CAP框架实现原理
    • 3.MediatR
      • 3.1 使用Mediator实现命令查询职责分离模式(CQRS)
        • 3.1.1 核心对象
      • 3.2 处理领域事件
        • 3.2.1 核心对象

1.集成事件

1.1 定义

集成事件目的是为了实现系统的集成,主要是用来在系统多个微服务之间相互传递事件,实现方式有两种

  • 发布、订阅通过EventBus方式
  • 通过观察者模式,由观察者将事件发给关注事件的人

1.2 集成事件工作原理

在这里插入图片描述

// 定义集成事件,命名:事件名称+IntergationEvent
public class OrderCreateIntergationEvent
{public OrderCreatedIntergrationEvent(long orderId) => OrderId = orderId;public long OrderId {get;}
}// 发布
public class OrderCreateDomainEventHandler : IDomainEventHandler<OrderCreateDomainEvent>
{// 发送集成事件的接口框架ICapPublisher _capPublisher;public OrderCreateDomainEventHandler(ICapPublisher capPublisher){_capPublisher = capPublisher;}public async Task Handle(OrderCreatedDomainEvent notification,CancellationToken cancelationToken){// 将名称为 "OrderCreated"的集成事件发送出去await _capPublisher.PublishAsync("OrderCreated",new OrderCreatedIntergrationEvent(notification.Order.Id))}
}// 订阅服务
public class SubscriberService : ISubscriberService,ICapSubscribe
{IMediator _mediator;public SubscriberService(IMediator mediator){_mediator = mediator;}[CapSubscribe("OrderPaymentSuccessed")]public void OrderPaymentSuccessed(OrderPaymentSuccessedIntergrationEvent envent){// TODO...}}

1.3 总结

  • 集成事件是跨服务的领域事件
  • 集成事件一般由领域事件驱动触发
  • 不通过事务来处理集成事件(实现最终一致性)
  • 仅在必要的情况下定义和使用集成事件

2.使用RabbitMQ来实现EventBus

2.1 RabbitMQ安装

进入RabbitMQ网站下载
RabbitMQ下载地址

2.2 CAP框架实现RabbitMQ

2.2.1 CAP框架实现架构

在这里插入图片描述

CAP框架实际是实现了OutBox的设计模式
OutBox设计模式是在每一个微服务中,比如微服务A的数据库A中建立两张表。一张publish事件表和一张receive事件表,这两张事件表用来记录微服务A发出和接收到的事件。当需要发出事件时,会把事件的存储逻辑和业务逻辑的事务合并,在同一个事务里提交,也就意味着当业务逻辑提交成功时,事件表里面的事件是一定存在的,它是与业务逻辑的事务是强绑定的,这就保证了所发出的事件是与业务逻辑一致的。接下来就是由组件负责将事件表中的事件全部发送到EventBus中,比如RabbitMQ消息队列中,由接受方订阅。
对于订阅事件,设计模式是同理。当应用程序从消息队列中获取到消息时,就会将这些消息持久化到数据库中的receive事件表中,这样就可以在本地进行事件的处理、失败重试等操作,这都是由CAP框架来完成。

// 演示代码
private IDbContextTransaction _currentTransaction;public Task<IDbContextTransaction> BeginTransactionAsync()
{if(_currentTransaction == null) return null;// 将业务存储放在同一个事务中,使得事务提交或回滚时,事件与业务逻辑的存取都是一致的_currentTransaction = DataBase.BeginTransaction(_capBus,autoCommit:false);return Task.FromResult(_currentTransaction);
}// 服务配置
public static IServiceCollection AddEventBus(this IServiceCollection services,IConfiguration configuration)
{services.AddTransient<ISubscriberService,SubscriberService>();services.AddCap(options =>{// 基于DomainContext实现EventBusoptions.UseEntityFramework<DomainContext>();// 使用RabbitMQ作为消息队列的存储options.UseRabbitMQ(options =>{// RabbitMQ配置configuration.GetSection("RabbitMQ").Bind(options);});};return services;
}

2.2.2 CAP框架实现原理

  • 事件表
  • 事务控制

3.MediatR

3.1 使用Mediator实现命令查询职责分离模式(CQRS)

3.1.1 核心对象

  • IMediator
  • IRequest、IRequest< T>
  • IRequestHandler< in TRquest,TResponse>
async static Task Main(string[] args)
{var services = new ServiceCollection();services.AddMediatR(typeof(Program).Assembly);var serviceProvider = services.BuildServiceProvider();var mediator = serviceProvider.GetService<IMediator>();await mediator.Send(new MyCommand{CommandName= "cmd01"});
}class MyCommand : IRequest<long>
{public string CommandName {get;set;}
}// 命令处理器定义
class MyCommandHandler : IRequestHandler<MyCommand,long>
{public Task<long> Handle(MyCommand request,CancellationToken cancelationToken){ConsoleWriteLine($@"MyCommandHandler 执行命令{request.CommandName}");return Task.FromResult(10L);}
}

通过中介者模式(MediatoR),可以将命令的构造和命令的处理分离开

3.2 处理领域事件

3.2.1 核心对象

  • IMediator
  • INotification
  • INotificationHandler< in TNotification>

async static Task Main(string[] args)
{var services = new ServiceCollection();services.AddMediatR(typeof(Program).Assembly);var serviceProvider = services.BuildServiceProvider();var mediator = serviceProvider.GetService<IMediator>();//await mediator.Publish(new MyEvent{EventName= "Event01"});Console.WriteLine("Hello World");
}class MyEvent : INotification
{public string EventName {get;set;}
}internal class MyEventHandler : INotificationHandler<MyEvent>
{public Task Handle(MyEvent notification,CancellationToken cancelationToken){Console.WriteLine($"MyEventHandle执行:{notification.EventName}");return Task.CompletedTask;}
}internal class MyEventHandler2 : INotificationHandler<MyEvent>
{public Task Handle(MyEvent notification,CancellationToken cancellationToken){Console.WriteLine($"MyEventHandle2执行:{notification.EventName}");return Task.CompletedTask;}
}

INotification可以注册多个,是一对多的关系,借助此我们可以对领域事件定义多个处理器

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/86537.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

matlab 点云的二进制形状描述子

目录 一、功能概述1、算法概述2、主要函数3、参考文献二、代码示例三、结果展示四、参数解析输入参数名称-值对应参数输出参数五、参考链接本文由CSDN点云侠原创,

linux+QT+FFmpeg 6.0,把多个QImage组合成一个视频

直接上代码吧: RecordingThread.h#ifndef RECORDINGTHREAD_H #define RECORDINGTHREAD_H #include "QTimer" #include <QObject> #include <QImage> #include <QQueue>extern "C"{//因为FFmpeg是c语言,QT里面调用的话需要extern "C…

【【萌新的STM32学习-16中断的基本介绍1】】

萌新的STM32学习-16中断的基本介绍1 中断 什么是中断 中断是打断CPU执行正常的程序&#xff0c;转而处理紧急程序&#xff0c;然后返回原暂停的程序继续执行&#xff0c;就叫中断 中断的作用 实时控制 &#xff1a; 就像对温度进行控制 故障控制 &#xff1a; 第一时间对突发情…

ICS PA1

ICS PA1 init.shmake 编译加速ISA计算机是个状态机程序是个状态机准备第一个客户程序parse_argsinit_randinit_loginit_meminit_isa load_img剩余的初始化工作运行第一个客户程序调试&#xff1a;零断点TUI 基础设施单步执行打印寄存器状态扫描内存 表达式求值词法分析递归求值…

指针C语言

1指针方式 1.int a,*p&a; 2. int a;int *p&a;特点&#xff1a; 1.指针变量与类型无关&#xff0c;在TC占2字节&#xff0c;在VC下占四字节 2.指针变量的引用 1.直接引用 2.间接引用 注意*的运算对象必须为地址 *p1; //相当于取p指针指向的值然后&#xff0b;1 int …

Zabbix下载安装及SNMP Get使用

帮助文档&#xff1a;6. Zabbix Appliance 一、zabbix下载安装 1、获取Zabbix Appliance镜像 Download Zabbix appliance 2、使用该镜像创建虚拟机 3、打开虚拟机控制台自动安装&#xff0c;等待安装完成即可 默认配置 系统/数据库&#xff1a;root:zabbix Zabbix 前端&am…

django的简易的图书管理系统jsp书店进销存源代码MySQL

本项目为前几天收费帮学妹做的一个项目&#xff0c;Java EE JSP项目&#xff0c;在工作环境中基本使用不到&#xff0c;但是很多学校把这个当作编程入门的项目来做&#xff0c;故分享出本项目供初学者参考。 一、项目描述 django的简易的图书管理系统 系统有1权限&#xff1a…

STM32移植ST77891.69寸屏幕并移植lvgl8.0.2(按键输入设备)一些心得

学习目标: 将ST7789(1.69寸圆角屏SPI)驱动移植+lvgl移植+按键当作输入设备 学习内容: 驱动移植lvgl移植按键移植软件使用正片开始: 先说说这块屏幕的介绍呗 ST7789屏幕是一种高性能的液晶显示屏,它具有高清晰度、高亮度、低功耗等优点。它采用了SPI接口通信,可以实现快速…

无涯教程-聚类算法 - K-Means

K-均值聚类算法计算质心并进行迭代&#xff0c;直到找到最佳质心为止&#xff0c;它假定群集的数目是已知的&#xff0c;它也称为扁平聚类算法。通过算法从数据中识别出的簇数以K均值中的" K"表示。 在该算法中&#xff0c;将数据点分配给群集&#xff0c;以使数据点…

python 模块BeautifulSoup 从HTML或XML文件中提取数据

一、安装 Beautiful Soup 是一个HTML/XML的解析器&#xff0c;主要的功能也是如何解析和提取 HTML/XML 数据。 lxml 只会局部遍历&#xff0c;而Beautiful Soup 是基于HTML DOM的&#xff0c;会载入整个文档&#xff0c;解析整个DOM树&#xff0c;因此时间和内存开销都会大很多…

206.Flink(一):flink概述,flink集群搭建,flink中执行任务,单节点、yarn运行模式,三种部署模式的具体实现

一、Flink概述 1.基本描述 Flink官网地址:Apache Flink — Stateful Computations over Data Streams | Apache Flink Flink是一个框架和分布式处理引擎,用于对无界和有界数据流进行有状态计算。 2.有界流和无界流 无界流(流): 有定义流的开始,没有定义结束。会无休止…

【Python】从入门到上头—Python基础(2)

文章目录 一.基础语法1.编码2.标识符3.保留字4.注释5.行与缩进6.多行语句7.数字(Number)类型8.字符串(String)9.空行10.等待用户输入11.同一行显示多条语句12.多个语句构成代码组13.print 输出14.import 与 from...import 二.基本数据类型1.变量和赋值2.多个变量赋值3.标准数据…