Asp.net core中RedisMQ的简单应用
最近一个外部的项目,使用到了消息队列,本来是用rabbitmq实现的,但是由于是部署到别人家的服务器上,想尽量简化一些,项目中本来也要接入了redis缓存,就尝试使用redis来实现简单的消息队列。
使用redis做消息队列有两种方法,一种是使用pub/sub,另一种是使用list结构,配合brpop来消费。这两种方式各有特点,这里简述一下:
- pub/sub模式,支持多客户端消费,但是不支持持久化,这就意味着客户端断开的时间内发布的消息将会全部舍弃掉。
- list配合brpop,默认不支持多客户端消费,支持持久化。这种模式的多客户端消费可以变相实现,比如下面的伪代码:
#第一步push消息到队列
lpush listA msg
#第二步,一个专门的分发客户端取出消息,push到各个子队列
var msg=brpop listA
lpush listA1 msg
lpush listA2 msg
......
#第三步,多个客户端从对应的队列消费消息
var client1_msg= brpop listA1
var client2_msg= brpop listA2
......
消息丢失不太可取,所以我选择了list ,下一步需要选择一个合适的客户端。
Stackexchange.redis 算是一个老牌的客户端了,但是由于其采用多路复用的模式,没法支持Redis的blocking pops特性。所以我采用了国人写的CSRedisCore。
首先需要在appsettings.json中添加redis的连接字符串:
{
"ConnectionStrings": {
"redis": "{ip}:{port},password=123456,prefix=my_"
}
}
具体配置请参考github上的文档:https://github.com/2881099/csredis
然后在startup.cs的ConfigureServices中配置redis:
public void ConfigureServices(IServiceCollection services)
{
//redis配置
RedisHelper.Initialization(new CSRedis.CSRedisClient(Configuration.GetConnectionString("redis")));
}
当然也可以使用依赖注入的方式添加CSRedisClient实例,这个不纠结。
在项目中有好几处使用到了队列,所以先封装一个消费服务:
public abstract class RedisMQConsumer : BackgroundService
{
protected abstract string CacheKey { get; }
protected ILogger<RedisMQConsumer> logger;
public RedisMQConsumer(ILogger<RedisMQConsumer> logger)
{
this.logger = logger;
}
protected override Task ExecuteAsync(CancellationToken stoppingToken)
{
return Task.Run( async() =>
{
while (!stoppingToken.IsCancellationRequested)
{
try
{
var msg = RedisHelper.BRPop(5, CacheKey);
try
{
if (string.IsNullOrEmpty(msg)) continue;
if (!Process(msg))
{
//加入错误处理队列,可以在后台写功能手动处理
RedisHelper.LPush(CacheKey + "_err", msg);
}
}
catch (Exception exp)
{
//加入错误处理队列,可以在后台写功能手动处理
RedisHelper.LPush(CacheKey + "_err", msg);
logger.LogError(exp, "RedisMQConsumer Execute error");
}
}
catch
{
//网络可能中断
await Task.Delay(TimeSpan.FromSeconds(5), stoppingToken);
}
}
}, stoppingToken);
}
protected abstract bool Process(string message);
}
然后就可以继承RedisMQConsumer,编写实际逻辑:
public class AddOrderMQConsumer : RedisMQConsumer
{
public AddOrderMQConsumer(ILogger<RedisMQConsumer> logger) : base(logger)
{
}
protected override string CacheKey => "addOrder";
protected override bool Process(string message)
{
//处理逻辑
return true;
}
}
最后把消费服务添加到startup.cs中:
public void ConfigureServices(IServiceCollection services)
{
//redis配置
RedisHelper.Initialization(new CSRedis.CSRedisClient(Configuration.GetConnectionString("redis")));
//redis消息队列消费服务,放在redis配置下方
services.AddHostedService<AddOrderListener>();
}
经测试,还算稳定,小并发项目可以使用。
Asp.net core中RedisMQ的简单应用的更多相关文章
- asp .net core中swagger的简单使用
相信swagger大家不太陌生,简单来说就是把web api接口以ui的形式呈现到页面上,供方便调用和展示.这边文章就带大家初步简单使用swagger. (1)首先需要安装包:Swashbuckle. ...
- 在Asp.Net Core中添加区域的简单实现
使用区域,可以有效的对业务进行隔离,各种业务及分工可以更灵活.在Asp.Net Core中启用区域也是极简单的. 使用步骤: 1.在 Startup.cs 中添加区域的路由: app.UseMvc(r ...
- Hangfire在ASP.NET CORE中的简单实现
hangfire是执行后台任务的利器,具体请看官网介绍:https://www.hangfire.io/ 新建一个asp.net core mvc 项目 引入nuget包 Hangfire.AspNe ...
- 在ASP.NET Core中通过EF Core实现一个简单的全局过滤查询
前言 不知道大家是否和我有同样的问题: 一般在数据库的设计阶段,会制定一些默认的规则,其中有一条硬性规定就是一定不要对任何表中的数据执行delete硬删除操作,因为每条数据对我们来说都是有用的,并且是 ...
- 如何简单的在 ASP.NET Core 中集成 JWT 认证?
前情提要:ASP.NET Core 使用 JWT 搭建分布式无状态身份验证系统 文章超长预警(1万字以上),不想看全部实现过程的同学可以直接跳转到末尾查看成果或者一键安装相关的 nuget 包 自上一 ...
- Hangfire在ASP.NET CORE中的简单实现方法
hangfire是执行后台任务的利器,具体请看官网介绍:https://www.hangfire.io/ 新建一个asp.net core mvc 项目 引入nuget包 Hangfire.AspNe ...
- ASP.NET Core 中的那些认证中间件及一些重要知识点
前言 在读这篇文章之间,建议先看一下我的 ASP.NET Core 之 Identity 入门系列(一,二,三)奠定一下基础. 有关于 Authentication 的知识太广,所以本篇介绍几个在 A ...
- 在ASP.NET Core中使用百度在线编辑器UEditor
在ASP.NET Core中使用百度在线编辑器UEditor 0x00 起因 最近需要一个在线编辑器,之前听人说过百度的UEditor不错,去官网下了一个.不过服务端只有ASP.NET版的,如果是为了 ...
- ASP.NET Core中的依赖注入(1):控制反转(IoC)
ASP.NET Core在启动以及后续针对每个请求的处理过程中的各个环节都需要相应的组件提供相应的服务,为了方便对这些组件进行定制,ASP.NET通过定义接口的方式对它们进行了"标准化&qu ...
随机推荐
- vite 搭建Vue3.0项目
1.全局安装vite:npm install create-vite-app -g 2.创建项目:npx create-vite-app project-name 3.cd project-name ...
- linux 图解笔记
- Web安全常见漏洞修复建议
转载地址:https://security.pingan.com/blog/17.html SQL注入 在服务器端要对所有的输入数据验证有效性. 在处理输入之前,验证所有客户端提供的数据,包括所有的参 ...
- php 序列化和反序列化的作用及使用
1.序列化是什么意思呢? 序列化就是把本来不能直接存储的数据转换成可存储的数据,并且不会丢掉数据格式 serialize(); 2.反序列化是什么意思呢? 其实就是字面的意思,把序列化的数据,转换成我 ...
- pandas 生成html文档,支持可添加多个表
如何通过pandas生成html格式?如何通过pandas生成html文件文件中包含多个表单Balance_64_data = pd.read_sql(Balance_64_sql,engine)df ...
- 怎么用MindManager2019去做一个好的网络图
大家知道网络图吗?是由作业(箭线).事件(又称节点)和路线三个因素组成的.它是一种图解模型,形状如同网络,故称为网络图.运用网络图能够使步骤简洁明了,今天我我们就说一说网络图软件MindManager ...
- Lombok之@Builder注解
Lombok之@Builder注解 前言 Lombok大家都知道,在使用POJO过程中,它给我们带来了很多便利,省下大量写get.set方法.构造器.equal.toString方法的时间.除此之外, ...
- yii2.0 ActiveForm 单选框与复选框使用
yii2.0 中的ActiveForm 复选框的使用 默认的复选框选项为纵向的<?= $form->field($model, 'line')->checkboxList(Pictu ...
- kafka producer 概要(看源码前,最好能掌握)
kafakproducer概要(看源码前,最好能理解) 摘要 kafak 被设计用来作为一个统一的平台来处理庞大的数据的实时工具,在设计上有诸多变态的要求 它必须具有高吞吐量才能支持大量事件流 ...
- 牛客练习赛69 火柴排队 题解(dp)
题目链接 题目大意 给你一个长为n(n<=5e3)的数组a.随机使得k个元素增加d.要你求多大的概率使得,这些数组元素的相对大小不发生改变 输出 n 行每行一个整数,第 i 行的整数表示 k=i ...