• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
netcore_vue
博客园    首页    新随笔    联系   管理    订阅  订阅

微服务架构:事件总线、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这个主题,订阅了对应主题的应用接收到推送的新增货品数据后继续进行后续操作。

 

------------恢复内容结束------------

posted @ 2022-07-11 17:09  梦想代码-0431  阅读(900)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3