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

这篇具有很好参考价值的文章主要介绍了【微服务】02-集成事件与MediatR。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.集成事件

1.1 定义

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

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

1.2 集成事件工作原理

【微服务】02-集成事件与MediatR,微服务,NetCore,微服务,架构,.netcore,后端

// 定义集成事件,命名:事件名称+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框架实现架构

【微服务】02-集成事件与MediatR,微服务,NetCore,微服务,架构,.netcore,后端

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实现EventBus
		options.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可以注册多个,是一对多的关系,借助此我们可以对领域事件定义多个处理器文章来源地址https://www.toymoban.com/news/detail-677850.html

到了这里,关于【微服务】02-集成事件与MediatR的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • nacos实现Java和.NetCore的服务注册和调用

    用nacos作为服务注册中心,如何注册.NetCore服务,如何在Java中调用.NetCore服务呢?可以分为下面几个步骤:   0.运行nacos   1.开发.net core服务,然后调用nacos提供的.net core sdk注册服务。   2.开发Java服务,然后注册服务。   3.用RestTemplate调用.net core服务。   4.用OpenFeign调用服务

    2024年01月17日
    浏览(34)
  • 项目发布部署:如何发布.NETCore项目到IIS服务器?

    前言:本文将详细介绍如何发布.NET Core项目到IIS服务器。首先,第一步需要安装IIS,介绍了在本地电脑和服务器中进行安装。然后需要安装SDK和运行时才能发布.NETCore项目。其次介绍了如何发布.NETCore项目和Vue项目,并配置IIS。最后介绍了如何将项目部署到Service服务中。 (

    2024年02月13日
    浏览(42)
  • .NetCore gRpc 客户端与服务端的单工通信Demo

    方式一 使用vs 2022(也可以是其他版本)创建一个grpc的服务,如下这样 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uipEG9Xu-1687172462785)(C:UsersAdministratorAppDataRoamingTyporatypora-user-imagesimage-20230619183828284.png)] 简单方便,创建项目后的目录结构如下图

    2024年02月09日
    浏览(43)
  • 杨中科 .netcore 依赖注入

    生活中的“控制反转”:自己发电和用电网的电。 依赖注入(Dependency Injection,Dl)是控制反转:(Inversion of Control,l0c)思想的实现方式。 依赖注入简化模块的组装过程,降低模块之间的耦合度 缺点是? 你需要对一切流程很清楚。 \\\'怎样创建XX对象”----“我要XX对象 两种实现方式:

    2024年02月21日
    浏览(20)
  • .NetCore调用Soap接口

    添加服务引用的方式无法满足我请求Soap接口,所以写了个Soap帮助类,使用HttpClient的方式请求接口。 提示:以下是本篇文章正文内容,下面案例可供参考 一条 SOAP 消息就是一个普通的 XML 文档,包含下列元素: 必需的 Envelope 元素,可把此 XML 文档标识为一条 SOAP 消息 可选的

    2024年02月04日
    浏览(29)
  • netcore模型配置

    模型配置可以通过Fluent API和注解的方式 FluentAPI步骤 新建Products 和Category类 新建Products类 Products     新建Category类 Category 他们之间存在一对多的关系 配置实体属性 Fluent API  配置一对一的关系 一对一关系表示两个实体存在唯一的关系,每个实体只能关联到另一个实体 新建

    2024年02月16日
    浏览(27)
  • 【NetCore】03-依赖注入

    管理类之间的依赖,帮助我们在构建应用时遵循设计原则,确保代码的可维护性和可扩展性 依赖注入框架提供了对象创建和生命周期管理的核心能力,各个组件相互协作,也是由依赖注入框架的能力来实现的 组件包 Microsoft.Extensions.DependencyInjection.Abstractions Microsoft.Extensions.

    2024年02月15日
    浏览(30)
  • IIS 部署.NetCore

    https://dotnet.microsoft.com/download/dotnet/3.1/runtime Windows 安装,选择desktop apps 选择好版本后,点击去,找到Core运行时的支持:IIS runtime support,里面的Hosting Bundle(托管捆绑包)下载 设置无托管 参考地址 1、cmd输入命令,提示无法启动此程序,因为计算机中丢失 api-ms-win-crt-runtime-l

    2024年02月12日
    浏览(25)
  • 杨中科 .NETCORE NuGet

    Zack.EFCore.Batch 使用这个开发包Entity Framework Core用户可以使用LINQ语句删除或者更新多条数据库记录,操作只执行一条SQL语句并且不需要首先把实体对象加载到内存中。这个开发包支持Entity Framework Core 5.0以及更高版。 操作说明: 第一步 https://www.nuget.org 精准搜索 合适与不知道什

    2024年01月20日
    浏览(33)
  • .netcore基础知识(一)

    Python微信订餐小程序课程视频 https://edu.csdn.net/course/detail/36074 Python实战量化交易理财系统 https://edu.csdn.net/course/detail/35475 先来说说web服务器 先来一张图 一个典型的进程外托管模型 我们先看kestrel这一部分 我们在它前面放了一个方向代理服务器nginx 对http请求做预处理 kestrel本

    2024年02月09日
    浏览(24)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包