CAP带你轻松玩转Asp.Net Core消息队列
CAP是什么?
CAP是由我们园子里的杨晓东大神开发出来的一套分布式事务的决绝方案,是.Net Core Community中的第一个千星项目(目前已经1656 Star),具有轻量级、易使用、高性能等特点。
https://github.com/dotnetcore/CAP
本博客主要针对易用性这一点,展开叙述,一起看看CAP如何结合EF Core和RabbitMQ带领小白轻松走入分布式消息队列的世界。
准备
首先,你需要搭建一套RabbitMQ系统,搭建过程在此不再叙述,如果大家觉得麻烦,可以用我搭好的。
HostName: coderayu.cn UserName:guest Password:guest (仅仅可用作实验,数据丢失不负责)
创建Asp.Net Core 项目,并引入Nuget包
你可以运行以下下命令在你的项目中安装 CAP。
PM> Install-Package DotNetCore.CAP
如果你的消息队列使用的是 Kafka 的话,你可以:
PM> Install-Package DotNetCore.CAP.Kafka
如果你的消息队列使用的是 RabbitMQ 的话,你可以:
PM> Install-Package DotNetCore.CAP.RabbitMQ
CAP 提供了 Sql Server, MySql, PostgreSQL 的扩展作为数据库存储:
// 按需选择安装你正在使用的数据库
PM> Install-Package DotNetCore.CAP.SqlServer
PM> Install-Package DotNetCore.CAP.MySql
PM> Install-Package DotNetCore.CAP.PostgreSql
创建DbContext
因为我采用的是EF Core,所以首先要创建一个DbContext上下文,代码如下:
public class CapDbContext:DbContext
{
public CapDbContext(DbContextOptions options) : base(options)
{
}
}
Startup配置
首先需要在ConfigureServices函数中进行相关服务的注入,对应的操作和功能解释如下:
public void ConfigureServices(IServiceCollection services)
{
//注入DbContext上下文,如果用的是Mysql可能还需要添加Pomelo.EntityFrameworkCore.MySql这个Nuget包
services.AddDbContext<CapDbContext>(options =>
options.UseMySql("Server=127.0.0.1;Database=testcap;UserId=root;Password=123456;")); //配置CAP
services.AddCap(x =>
{
x.UseEntityFramework<CapDbContext>(); //启用操作面板
x.UseDashboard();
//使用RabbitMQ
x.UseRabbitMQ(rb =>
{
//rabbitmq服务器地址
rb.HostName = "coderayu.cn"; rb.UserName = "guest";
rb.Password = "guest"; //指定Topic exchange名称,不指定的话会用默认的
rb.ExchangeName = "cap.text.exchange";
}); //设置处理成功的数据在数据库中保存的时间(秒),为保证系统新能,数据会定期清理。
x.SucceedMessageExpiredAfter = * ; //设置失败重试次数
x.FailedRetryCount = ;
}); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
最后还要再Congiure中启用CAP中间件
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
//启用cap中间件
app.UseCap(); app.UseMvc();
}
利用EF Core生成CAP数据库
再程序包管理控制台中依此输入以下命令行
PM> Add-Migration Init
PM> update-database
如果成成功执行,那么打开数据库,就可以看到用来存储CAP发送和接收数据的表格了。

表格中每列的含义如下:

消息的发送和订阅
我们直接在ValuesController的基础上进行改造。
在 Controller 中注入 ICapPublisher 然后使用 ICapPublisher 进行消息发送
private readonly ICapPublisher _publisher;
public ValuesController(ICapPublisher publisher)
{
_publisher = publisher;
}
发送消息
[HttpGet]
public string Get(string message)
{
//"cap.test.queue"是发送的消息RouteKey,可以理解为消息管道的名称
_publisher.Publish("cap.test.queue",message); return "发送成功";
}
订阅消息
//"cap.test.queue"为发送消息时的RauteKey,也可以模糊匹配
//详情https://www.rabbitmq.com/tutorials/tutorial-four-dotnet.html
[CapSubscribe("cap.test.queue")]
public void HandleMessage(string message)
{
Console.Write(DateTime.Now.ToString()+"收到消息:"+message);
}
Run
启动程序后,首先看到CAP启动成功

紧随其后,消费者也就是我们的订阅方法在RabbitMQ服务器上注册成功。

发送消息,发送成功,如下

发送后,立即在控制台看到了订阅方法输出的结果。

消息的失败重试
在订阅方法中,如果抛出异常,那么CAP就会认为该条消息处理失败,会自动进行重试,重试次数在前方已经进行了配置。
我们把订阅方法做一个改动,打印接收的信息到控制台中,并抛出异常
//"cap.test.queue"为发送消息时的RauteKey,也可以模糊匹配
//详情https://www.rabbitmq.com/tutorials/tutorial-four-dotnet.html
[CapSubscribe("cap.test.queue")]
public void HandleMessage(string message)
{
Console.WriteLine(DateTime.Now.ToString()+"收到消息:"+message);
throw new Exception("测试失败重试");
}
可以看到,立即进行了三次重试

可是在前面,我们设置的失败重试次数是5次,为什么这里只重试三次吗?是不是要叫晓东过来改BUG了呢
?当然不是。
观察发现,CAP重试的前三次是立即进行的,而后面的重试,是每隔一段时间进行的,当在分布式通讯的过程中,可能出现了问题确实不会立即修复解决,可能过了一定时间,系统就自动恢复了,如网络抖动。
CAP仪表盘

发送成功了五条消息,成功接收处理了三条,两条处理失败,处理失败的任务,我们可以直接在面板中进行重新消费,可谓非常方便。

同时,处理失败的消息,点击消息的编号后,可以查看到消息的内容和异常原因。

CAP如此强大,让消息队列这种高大上产品操作So Easy,学会了CAP,也可以吹牛说,我也懂分布式任务处理啦
。
感谢晓东开发出如此强大的项目,同时感谢.Net Core Community。
参考 CAP Github wiki
https://github.com/dotnetcore/CAP/wiki
本博客Demo代码
https://github.com/liuzhenyulive/CAP.Demo
CAP带你轻松玩转Asp.Net Core消息队列的更多相关文章
- CAP带你轻松玩转ASP.NETCore消息队列
CAP是什么? CAP是由我们园子里的杨晓东大神开发出来的一套分布式事务的决绝方案,是.Net Core Community中的第一个千星项目(目前已经1656 Start),具有轻量级.易使用.高性 ...
- ASP.NET Core消息队列RabbitMQ基础入门实战演练
一.课程介绍 人生苦短,我用.NET Core!消息队列RabbitMQ大家相比都不陌生,本次分享课程阿笨将给大家分享一下在一般项目中99%都会用到的消息队列MQ的一个实战业务运用场景.本次分享课程不 ...
- 开发一个带UI的库(asp.net core 3.0)
在GitHub上有个项目,本来是作为自己研究学习.net core的Demo,没想到很多同学在看,还给了很多星,所以觉得应该升成3.0,整理一下,写成博分享给学习.net core的同学们. 项目名称 ...
- 玩转ASP.NET Core中的日志组件
简介 日志组件,作为程序员使用频率最高的组件,给程序员开发调试程序提供了必要的信息.ASP.NET Core中内置了一个通用日志接口ILogger,并实现了多种内置的日志提供器,例如 Console ...
- 微软Azure配置中心 App Configuration (一):轻松集成到Asp.Net Core
写在前面 在日常开发中,我这边比较熟悉的配置中心有,携程Apollo,阿里Nacos(配置中心,服务治理一体) 之前文章: Asp.Net Core与携程阿波罗(Apollo)的第一次亲密接触 总体来 ...
- 架构篇 | 带你轻松玩转 LAMP 网站架构平台(一)
作者 | JackTian 微信公众号 | 杰哥的IT之旅(ID:Jake_Internet) 转载请联系授权(微信ID:Hc220066)备注:来自博客园 1.什么是 LAMP 架构? LAMP 架 ...
- 新霸哥带你轻松玩转Oracle数据库
接触过软件开发的朋友可能都会知道oracle,在开发的过程中,数据存储都可能会用到oracle的,因为oracle具有处理速度快,安全级别特别的高.但是有一个缺点就是比较的贵,只有一个大型的公司才有可 ...
- 带你轻松玩转Git--图解三区结构
在上篇文章的结尾我们提到了Git 的三区结构,在版本控制体系中有这样两种体系结构,一种是两区结构一种是三区结构.接下来我们通过对Git三区的结构学习来帮助我们更好的去理解并运用Git. 两区结构是其他 ...
- 带你轻松玩转Git--瞬间创建本地仓库
在上一篇文章中我们对版本控制有了一个比较宏观的了解,同时也能够看到Git 所处在的历史地位.并且对版本控制系统的体系进行了一个宏观的对比,貌似让读者看起来挺复杂的样子. 笔者将会尽可能的简单向大家分享 ...
随机推荐
- Java Web Without SSM(前言)
是的,Spring,Mybaties确实给我们带来了方便的轻量级JavaWeb开发,但是,对于大部分中小系统来说,分层,框架,规范,已经成为一种累赘.实际的程序开发过程中,大部分时间都花在了" ...
- mongodb的安装使用,window和centos环境
官网:https://www.mongodb.org/downloads 版本:最终稳定版 (mongodb-win32-x86_64-2008plus-ssl-3.2.6-signed.msi 绿色 ...
- 使用webpack打包vue工程
记得去年十月份的时候,自己在研究webpack,当时只是知道大致的用法,写了一个简单的demo,现在,经过了7个月对公司产品架构的使用,以及对vue-cli的使用,在了解了实际应用中各种需求之后,我自 ...
- leetCode刷题(找到最长的连续不重复的字符串长度)
Given a string, find the length of the longest substring without repeating characters. Examples: Giv ...
- 使用WSL连接Docker for Windows
在Windows下安装Docker for Windows Cotana搜索功能,打开Windows的Hype-v功能(注:会影响Virtualbox和Vmware的使用)并重启电脑. 从Docker ...
- 卸载重装Mysql
卸载重装前请备份数据库 卸载 sudo apt autoremove --purge mysql-server-core-5.7 清理残留 sudo rm -r /var/lib/mysql* sud ...
- SpringMVC解决跨域的两种方案
1. 什么是跨域 2. 跨域的应用情景 3. 通过注解的方式允许跨域 4. 通过配置文件的方式允许跨域 1. 什么是跨域 跨域,即跨站HTTP请求(Cross-site HTTP request),指 ...
- Python 内置的一些高效率函数用法
1. filter(function,sequence) 将sequence中的每个元素,依次传进function函数(可以自定义,返回的结果是True或者False)筛选,返回符合条件的元素,重组 ...
- R语法学习 第十二篇:因子
因子(factor)是R语言中比较特殊的一个类型, 它是一个用于存储类别的类型,因子的行为有时像字符串,有时像整数.因子也是一个向量,每个元素都是字符类型.因子具有因子水平(Levels),用于限制因 ...
- 去重是distinct还是group by?
distinct简单来说就是用来去重的,而group by的设计目的则是用来聚合统计的,两者在能够实现的功能上有些相同之处,但应该仔细区分,因为用错场景的话,效率相差可以倍计. 单纯的去重操作使用di ...