微服务架构:事件总线、CAP、RabbitMQ及在ABPVnext中应用
------------恢复内容开始------------
首先了解下其概念
CAP是一个在分布式系统(SOA)或微服务系统(MicroService)中实现事件总线及最终一致性(分布式事务)的一个开源的C#库,具有轻量级,高性能,易使用等特点。
CAP 具有Event Bus的所有功能,简化EventBus中的发布/订阅
CAP 具有消息持久化的功能,服务进行重启或者宕机不比担心消息丢失保证可靠性
Cap支持事务,通过捕获数据库上下文连接对象实现消息事务,消息持久化
CAP 实现了分布式事务中的最终一致性,你不用再去处理这些琐碎的细节。
示意图
使用起来非常简单,主要通过这个类来实现
l 发布:ICapPublisher
l 订阅:CapSubscribe
环境
l Win10
l VS2022
l .NET5.0
l DotNetCore.CAP 5.0.1
l DotNetCore.CAP.RabbitMQ 5.0.1
l DotNetCore.CAP.SqlServer 5.0.1
l CAP.Dashboard 5.0.0
l Microsoft.EntityFrameworkCore.Design 5.0.0
l SQLserver2012
实时数据传输与消息队列
实时数据传输和消息队列是两类不同的技术方案,有着不同的应用场景,但又有一定的相似性。实时数据传输更偏重于“实时”两个字,要求保证数据的及时有效交换,多用于多媒体相关的业务场景,常见的技术栈有WebRTC、SignalR等;消息队列更偏重于“可靠”,多用于能够容忍一定延迟但要求数据可靠到达的业务场景,常见的技术栈有ActiveMQ、RabbitMQ、Kafka等。相似的地方是,实时数据传输与消息队列基本都有诸如分布式、高并发之类的解决方案,而且常用的也都是订阅/发布模式。订阅/发布模式也并不是实时数据传输或消息队列的专利,很多开发语言、技术栈都有这样的机制,这样的机制也更有利于我们快速使用拥有订阅/发布模式的技术栈。
安装并配置CAP
暂不细究CAP是什么,先看能干什么。打开NuGet管理器为应用层AbpDemo.Application安装DotNetCore.CAP程序包,为分布式服务层和展现层AbpDemo.Web安装DotNetCore.CAP.RabbitMQ和DotNetCore.CAP.MySql程序包。
在启动类中添加AddCAP方法
public class Startup { private readonly IConfigurationRoot _appConfiguration; public IServiceProvider ConfigureServices(IServiceCollection services) { //... #region CAP services.AddCap(x => { //配置数据库连接 string connectionString = _appConfiguration["ConnectionStrings:Default"]; x.UseMySql(connectionString); //配置消息队列RabbitMQ x.UseRabbitMQ(mq => { mq.HostName = configuration["RabbitMQ:Connections:Default:HostName"]; mq.Port = int.Parse(configuration["RabbitMQ:Connections:Default:Port"]); mq.UserName = configuration["RabbitMQ:Connections:Default:UserName"]; mq.Password = configuration["RabbitMQ:Connections:Default:Password"]; }); }); #endregion //... } //... }
然后在Application项目的应用服务中添加带有CAP特性的方法。包括订阅数据的方法和发布数据的方法
/// <summary>
/// 数据订阅服务
/// </summary>
public class SubscribeAppService : ISubscribeAppService
{
/// <summary>
/// 货品数据同步
/// </summary>
/// <param name="goods"></param>
[CapSubscribe("goods-sync")]
public void SubscribeGoods(Goods goods)
{
//...
}
}
public interface ISubscribeAppService:ICapSubscribe
{
void SubscribeGoods(Goods goods);
}
另外不要忘了在Web项目的Startup启动类中注册数据订阅服务
services.AddTransient<ISubscribeAppService, SubscribeAppService>();
发布数据
/// <summary> /// 货品管理-应用服务 /// </summary> public class GoodsAppService: AbpDemoAppServiceBase<Goods,DetailGoodsDto,string,CreateGoodsDto,UpdateGoodsDto,PagedGoodsDto>,IGoodsAppService { private readonly IGoodsRecordManager _goodsRecordManager;//出入库记录领域服务 private readonly IGoodsManager _goodsManager;//货品管理领域服务 private readonly IMessageManager _messageManager;//实时消息领域服务 private readonly ICapPublisher _capPublisher;//数据发布器 public GoodsAppService(IRepository<Goods,string> repository, IGoodsRecordManager goodsRecordManager, IGoodsManager goodsManager, IMessageManager messageManager, ICapPublisher capPublisher) :base(repository) { _goodsRecordManager = goodsRecordManager; _goodsManager = goodsManager; _messageManager = messageManager; EventBus = NullEventBus.Instance; _capPublisher = capPublisher; } public override Task<DetailGoodsDto> Create(CreateGoodsDto input) { //新增货品时同步至备份库 Goods goods = input.MapTo<Goods>(); _capPublisher.Publish<Goods>("goods-sync", goods);//发布数据 return base.Create(input); } }
简单来说,现在很多的分布式应用都存在分库或分应用的场景。还是以之前的货品管理为例,假设货品管理的应用程序连接数据库且需要数据同步,也就是主应用的数据变化时需要将数据同步到其他应用。上面一系列的代码描述的就是这一过程:应用连接MySQL数据库,通过API接口新增货品时,将新增货品的数据发布到应用所连接的消息队列RabbitMQ中,对应的是goods-sync这个主题,订阅了对应主题的应用接收到推送的新增货品数据后继续进行后续操作。
------------恢复内容结束------------
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)