【微服务】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.mzph.cn/news/55763.shtml

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

相关文章

Java线程 - 详解(1)

一&#xff0c;创建线程 方法一&#xff1a;继承Thread类 class MyThread extends Thread{Overridepublic void run() {System.out.println("线程1");} }public class Test {public static void main(String[] args) {MyThread myThread new MyThread();myThread.…

【C语言】2023.8.27C语言入学考试复盘总结

前言 本篇文章记录的是对于2023年8月27日的 C语言 的入学考试的整理总结 成绩&#xff1a;220/240 题目&#xff1a;9/12 错题整理 首先先对于我没做出来的三道题做一个整理 错题1&#xff1a;7-4 分段函数PLUS 题干 以下是一个二元分段函数&#xff0c;请你根据所给的函…

android系统启动流程之init启动分析

先根据上图来描述下安卓整个系统的启动流程&#xff1a; 当上电时&#xff0c;系统先执行BootRom, 加载引导程序执行。 然后进入bootloader&#xff0c;在安卓系统中基本上这个bootloader是uboot, 通过uboot引导启动内核&#xff0c;此时运行在kernel空间&#xff0c;这时的i…

基于全新电脑环境安装pytorch的GPU版本

前言&#xff1a; 距离第一次安装深度学习的GPU环境已经过去了4年多&#xff08;当时TensorFlow特别麻烦&#xff09;&#xff0c;现在发现安装pytorch的GPU版本还是很简单方便的&#xff0c;流程记录如下。 安装步骤&#xff1a; 步骤一&#xff1a;官网下载Anaconda Free…

研磨设计模式day11观察者模式

目录 场景 代码示例 定义 观察者模式的优缺点 本质 何时选用 简单变型-区别对待观察者 场景 我是一家报社&#xff0c;每当我发布一个新的报纸时&#xff0c;所有订阅我家报社的读者都可以接收到 代码示例 报纸对象 package day11观察者模式;import java.util.Observ…

Python+TinyPNG熊猫网站自动化的压缩图片

前言 本篇在讲什么 PythonTinyPNG自动化处理图片 本篇需要什么 对Python语法有简单认知 依赖Python2.7环境 依赖TinyPNG工具 本篇的特色 具有全流程的图文教学 重实践&#xff0c;轻理论&#xff0c;快速上手 提供全流程的源码内容 ★提高阅读体验★ &#x1f449;…

AI + Milvus:将时尚应用搭建进行到底

在上一篇文章中&#xff0c;我们学习了如何利用人工智能技术&#xff08;例如开源 AI 向量数据库 Milvus 和 Hugging Face 模型&#xff09;寻找与自己穿搭风格相似的明星。在这篇文章中&#xff0c;我们将进一步介绍如何通过对上篇文章中的项目代码稍作修改&#xff0c;获得更…

[管理与领导-53]:IT基层管理者 - 8项核心技能 - 8 - 持续改进

前言&#xff1a; 管理者存在的价值就是制定目标&#xff0c;即目标管理、通过团队&#xff08;他人&#xff09;拿到结果。 要想通过他人拿到结果&#xff1a; &#xff08;1&#xff09;目标&#xff1a;制定符合SMART原则的符合业务需求的目标&#xff0c;团队跳一跳就可以…

Microsoft正在将Python引入Excel

Excel和Python这两个世界正在碰撞&#xff0c;这要归功于Microsoft的新集成&#xff0c;以促进数据分析和可视化 Microsoft正在将流行的编程语言Python引入Excel。该功能的公共预览版现已推出&#xff0c;允许Excel用户操作和分析来自Python的数据。 “您可以使用 Python 绘图…

Git向远程仓库与推送以及拉取远程仓库

理解分布式版本控制系统 1.中央服务器 我们⽬前所说的所有内容&#xff08;⼯作区&#xff0c;暂存区&#xff0c;版本库等等&#xff09;&#xff0c;都是在本地也就是在你的笔记本或者计算机上。⽽我们的 Git 其实是分布式版本控制系统&#xff01;什么意思呢? 那我们多人…

JavaWeb 速通JQuery

目录 一、JQuery快速入门 1.基本介绍 : 2.入门案例 : 二、JQuery对象 1.基本介绍 : 2.DOM对象 --> JQuery对象 : 3.JQuery对象 --> DOM对象 : 三、JQuery选择器 1.简介 : 2.基本选择器 : 3.层次选择器 : 4.过滤选择器 : 4.1 基础过滤选择器 4.2 内容过滤选择…

Vue中ElementUI结合transform使用时,发现弹框定位不准确问题

在近期开发中&#xff0c;需要将1920*1080放到更大像素大屏上演示&#xff0c;所以需要使用到transform来对页面进行缩放&#xff0c;但是此时发现弹框定位出错问题&#xff0c;无法准备定位到实际位置。 查看element-ui官方文档无果后&#xff0c;打算更换新的框架进行开发&am…

国产系统下开发QT程序总结

国产系统下开发QT程序总结 1. 国产系统简介 开发国产系统客户端的过程中&#xff0c;会出现兼容性问题。以下介绍Kylin和UOS环境下开发QT程序&#xff0c; 首先麒麟和统信这两个系统基于Ubuntu开发的。所以在Ubuntu开发理论上在国产系统上也能运行。芯片架构又分为amd,arm,mi…

飞凌嵌入式受邀参加「RISC-V芯片应用交流会」并发表主题演讲

8月23日下午&#xff0c;在第三届RISC-V中国峰会现场&#xff0c;由赛昉科技主办的「RISC-V芯片应用交流会」吸引了诸多行业伙伴和专家到场参与。此次会议旨在分享赛昉科技高性能RISC-V芯片的软件生态、应用产品、解决方案等全面进展&#xff0c;共同探讨RISC-V芯片的未来发展和…

javaee spring 自动注入,如果满足条件的类有多个如何区别

如图IDrinkDao有两个实现类 方法一 方法二 Resource(name“对象名”) Resource(name"oracleDrinkDao") private IDrinkDao drinkDao;

Java --- 异常处理

目录 一、什么是异常 二、异常抛出机制 三、如何对待异常 四、 Java异常体系 4.1、Throwable 4.2、Error 4.2、Exception 4.2.1、编译时异常 4.2.2、运行时期异常 五、异常处理 5.1、捕获异常&#xff08;try-catch&#xff09; 5.1.2、catch中异常处理方式 …

你对SPA单页面的理解,它的优缺点分别是什么?如何实现SPA应用呢?

一、什么是SPA SPA&#xff08;single-page application&#xff09;&#xff0c;翻译过来就是单页应用SPA是一种网络应用程序或网站的模型&#xff0c;它通过动态重写当前页面来与用户交互&#xff0c;这种方法避免了页面之间切换打断用户体验在单页应用中&#xff0c;所有必…

TCP的三次握手 四次挥手以及TCP的11种状态

三次握手流程&#xff1a; 客户端给服务端发送数据时&#xff0c;数据包中带有一个头&#xff0c;这个头就是前几十个字节&#xff0c;就是下面这张图。从源端口号&#xff0c;目的端口号&#xff0c;一直到序列号&#xff0c;直到Options。第一个包会将这前十几个字节中的SYN置…

12. 完整模型训练套路

12.1 CIFAR 10 model 网络模型 ① 下面用 CIFAR 10 model网络来完成分类问题&#xff0c;网络模型如下图所示。 12.2 DataLoader加载数据集 import torchvision from torch import nn from torch.utils.data import DataLoader# 准备数据集 train_data torchvision.dataset…

C#,《小白学程序》第二课:数组与排序

1 文本格式 /// <summary> /// 《小白学程序》第二课&#xff1a;数组与排序 /// </summary> /// <param name"sender"></param> /// <param name"e"></param> private void button2_Click(object sender, EventArgs …