微服务架构:事件总线、消息队列CAP.RabbitMQ
参考:
事件总线
什么是事件总线
就是用来管理所有的事件的一种机制就称作为事件总线,包括事件发布,事件存储,事件订阅,事件处理的统称
作用
事件总线是一种机制,它允许不同的组件彼此通信而不彼此了解。 组件可以将事件发送到Eventbus,而无需知道是谁来接听或有多少其他人来接听。 组件也可以侦听Eventbus上的事件,而无需知道谁发送了事件。 这样,组件可以相互通信而无需相互依赖。 同样,很容易替换一个组件。 只要新组件了解正在发送和接收的事件,其他组件就永远不会知道
CAP框架
CAP 是一个EventBus,同时也是一个在微服务或者SOA系统中解决分布式事务问题的一个框架。它有助于创建可扩展,可靠并且易于更改的微服务系统。
CAP 支持以下几种运输方式:
存储方式分为内存和数据库
RabbitMQ
RabbitMQ是消息代理:它接受并转发消息。您可以将其视为邮局:将您要发布的邮件放在邮箱中时,可以确保Mailperson先生或女士最终将邮件传递给收件人。以此类推,RabbitMQ是一个邮箱,一个邮局和一个邮递员。
RabbitMQ与邮局之间的主要区别在于,它不处理纸张,而是接收,存储和转发数据消息的二进制斑点。
六种队列模式:先进先出,后进后出
发布订阅模式:一般是聚合服务发布消息给RabbitMQ,RabbitMQ再发消息发动订阅者服务,通过RabbitMQ解耦,两个服务不直接通信,是RabbitMQ调用服务,不再是聚合服务调用服务
- 发布(Publish):程序把请求消息发布给RabbitMQ后直接返回,不用再等请求执行完毕再返回,对应数据库发布表:Published
- 订阅(Subscrib):程序订阅RabbitMQ后,RabbitMQ把消息逐一推送给订阅者,也就是RabbitMQ调用订阅者服务,对应数据库订阅表:Received
连接参数:
- HostName: 宿主地址
- UserName: 用户名
- Password: 密码
- VirtualHost: 虚拟主机
- Port: 端口号
- TopicExchangeName: CAP默认Exchange名称
- QueueMessageExpires: 队列中消息自动删除时间
- ConnectionFactoryOptions: 本机连接工厂选项
消费模式
参考:
微服务中使用CAP框架的RabbitMQ方式
环境准备
RabbitMQ的开发语言环境:Erlang下载地址
RabbitMQ下载地址
RabbitMQ启动
1、在安装目录下添加可视化插件命令
rabbitmq-plugins enable rabbitmq_management
2、在安装目录sbin文件夹下启动
rabbitmq-server
3、sbin文件夹下查看rabbitmq状态,最后两行就是端口号,默认是15672
rabbitmqctl status
4、在浏览器输入http://127.0.0.1:15672
访问rabbitmq后台系统,默认账号和密码都是:guest
队列跟踪trace
参考:https://www.cnblogs.com/li150dan/p/9529049.html
启动trace命令:rabbitmqctl trace_on
启动日志插件命令:rabbitmq-plugins enable rabbitmq_tracing
然后添加跟踪输入,需要输入账号密码
在项目中使用RabbitMQ
MicroService.Core项目安装NuGet包
- CAP: Nuget DotNetCore.CAP
- CAP传输器:Nuget DotNetCore.CAP.RabbitMQ
- CAPSql持久化:DotNetCore.CAP.SqlServer
- CAP内存持久化:DotNetCore.CAP.InMemoryStorage
在聚合服务 MicroService.AggregateService服务中startup.cs中使用CAP
// 添加事件总线cap services.AddCap(x => { // 使用内存存储消息(消息发送失败处理) x.UseInMemoryStorage();
//使用EntityFramework进行存储操作,指定数据库上下文就好,不用配置 //x.UseEntityFramework<AggregateContext>(); // 使用RabbitMQ进行事件中心处理 x.UseRabbitMQ(rb => { rb.HostName = "localhost"; rb.UserName = "guest"; rb.Password = "guest"; rb.Port = 5672; rb.VirtualHost = "/"; }); });
在聚合服务MicroService.AggregateService服务中AggregateController.cs中注入且使用ICapPublisher,把消息发布给RabbitMQ
using DotNetCore.CAP;
private readonly ICapPublisher capPublisher; public TeamsController(ICapPublisher capPublisher) { this.capPublisher = capPublisher; } //异步发布对象消息 capPublisher.PublishAsync<Video>("video.event.1", video);
在视频服务MicroService.VideoService服务startup.cs中使用CAP
// 添加事件总线cap services.AddCap(x => { // 使用RabbitMQ进行事件中心处理 x.UseRabbitMQ(rb => { rb.HostName = "localhost"; rb.UserName = "guest"; rb.Password = "guest"; rb.Port = 5672; rb.VirtualHost = "/"; }); });
在视频服务MicroService.VideoService服务VideoController.cs 的PostVideo方法上添加过滤器特性[CapSubscribe] ,从RabbitMQ中订阅,且处理这些请求
using DotNetCore.CAP; /// <summary> /// 视频添加: /// 从消息队列获取请求 /// </summary> /// <param name="Video"></param> /// <returns></returns> [NonAction] //指示控制器方法不是动作方法,不让控制器调用 [CapSubscribe("video.*")] //订阅消息:RabbitMQ推送消息给订阅者 public ActionResult<Video> PostVideo(Video Video) { Console.WriteLine($"接受到视频事件消息"); videoService.Create(Video); return CreatedAtAction("GetVideo", new { id = Video.Id }, Video); }
本文版权归作者和博客园共有,欢迎转载,但必须在文章页面给出原文链接,否则保留追究法律责任的权利。