使用Reids实现简单消息队列
队列操作
简单队列
利用List数据结构可以实现简单的队列,在于使用List提供插入和移除api来完成简单队列操作;
准备数据
获取数据
后入先出
使用redis提供的apiLPOP
可以从队列左边获取数据,也就是从队列的头部获取到最后插入的数据,也可以使用BLPOP
设置超时时间,从而做到等待数据写入;
先入先出
与上面的一样,只是把获取数据的方向改成另一边,使用RPOP
可以从队列右边获取数据,也就是从队列的尾部获取到最先插入的数据,也可以使用BRPOP
设置超时时间,从而做到等待数据写入;
等待
使用BLPOP
、BRPOP
可以移除并获取列表头部/尾部获取第一个元素;如果把BLPOP
命令的超时时间设置为0,表示一直阻塞,直到数据写入;
实现
到这就可以将List当成一个简单的队列,推送数据的生产者,将数据写入到List,然后消费者等着List中有数据,然后获取;
生产者
using StackExchange.Redis;
var connection = ConnectionMultiplexer.Connect("localhost");
var redis = connection.GetDatabase(1);
foreach (var i in Enumerable.Range(0,10))
{
await redis.ListLeftPushAsync("data",i);
Console.WriteLine($"写入 {i}");
Thread.Sleep(1000);
}
消费者
using StackExchange.Redis;
var connection = ConnectionMultiplexer.Connect("localhost");
var redis = connection.GetDatabase(1);
while (true)
{
var res = await redis.ListRightPopAsync("data");
if (!string.IsNullOrEmpty(res))
{
Console.WriteLine($"读取 {res}");
}
Thread.Sleep(1000);
}
至此,消息已经消费,但是消息的多播并不能实现,队列中的消息被移除了,另外的消费者就拿不到这条消息,同时ListRightPopAsync方法对应的redisRPOP
命令,StackExchange.Redis中不支持Redis中对应的BLPOP
、BRPOP
命令,但是可以使用发布订阅模式实现;
发布订阅
生产者
using StackExchange.Redis;
var connection = ConnectionMultiplexer.Connect("localhost");
var sub = connection.GetSubscriber();
foreach (var i in Enumerable.Range(0,10))
{
await sub.PublishAsync("channel", $"消息 {i}");
Console.WriteLine($"发布消息 {i}");
Thread.Sleep(1000);
}
Console.ReadLine();
消费者
using StackExchange.Redis;
var connection = ConnectionMultiplexer.Connect("localhost");
var sub = connection.GetSubscriber();
sub.Subscribe("channel",
(channel, message) =>
{
Console.WriteLine($"接收消息:{message}");
});
Console.ReadLine();
通过消息生产者将消息发布到某个channel,同时消费者订阅该channel,即可获取到消息;当有多个消费者也可以接受到消息了,如果在消费者订阅之前消息就已消费则不能再获取到该消息;
开启两个消费者,都订阅了同一channel,利用Sleep使消费者2晚一秒订阅到channel,导致没有接收到消息0;
如果想要做到消息的持久化可以同时将Redis的List利用起来,或者使用其他介质存一份,在消息发布的同时使用将消息推到List中,然后在消费者中去将消息移除,历史消息可以在订阅channel前获取到当前List中消息,开启一个线程去执行业务操作并移除当前消息;
生产者
using StackExchange.Redis;
var connection = ConnectionMultiplexer.Connect("localhost");
var redis = connection.GetDatabase(1);
var sub = connection.GetSubscriber();
foreach (var i in Enumerable.Range(0,100))
{
await redis.ListLeftPushAsync("historyMsg", $"消息 {i}");
await sub.PublishAsync("channel", $"消息 {i}");
Console.WriteLine($"发布消息 {i}");
Thread.Sleep(1000);
}
Console.ReadLine();
消费者
using StackExchange.Redis;
var connection = ConnectionMultiplexer.Connect("localhost");
var redis = connection.GetDatabase(1);
var sub = connection.GetSubscriber();
//这里可以选择不同消息持久化介质
var count = (await redis.ListRangeAsync("historyMsg")).Length;
if (count > 0)
{
await Task.Run(() =>
{
for (int i = 0; i < count; i++)
{
string result = redis.ListRightPop("historyMsg");
Console.WriteLine("处理历史消息:" + result);
}
});
}
sub.Subscribe("channel",
(channel, message) =>
{
redis.ListRightPop("historyMsg");
Console.WriteLine($"接收消息:{message}");
});
Console.ReadLine();
使用Reids实现简单消息队列的更多相关文章
- simple简单消息队列
一:介绍 1.优缺点 简单,但是耦合性较高. 这种模式是生产者与消费者一一对应,就是一个产生者,有一个消费者来消费. 如果,多个消费者想消费一个队列中的消息就不适合了.这种情况在后面会接着介绍. 2. ...
- Redis实现简单消息队列
http://www.jianshu.com/p/9c04890615ba 任务异步化 打开浏览器,输入地址,按下回车,打开了页面.于是一个HTTP请求(request)就由客户端发送到服务器,服务器 ...
- 用 Redis 实现 PHP 的简单消息队列
参考:PHP高级编程之消息队列 消息队列就是在消息的传输过程中,可以保存消息的容器. 常见用途: 存储转发:异步处理耗时的任务 分布式事务:多个消费者消费同一个消息队列 应对高并发:通过消息队列保存任 ...
- redis(五)---- 简单消息队列
消息队列一个消息的链表,是一个异步处理的数据处理引擎.不仅能够提高系统的负荷,还能够改善因网络阻塞导致的数据缺失.一般用于邮件发送.手机短信发送,数据表单提交.图片生成.视频转换.日志储存等. red ...
- RabbitMq(2) 简单消息队列
<dependency> <groupId>com.rabbitmq</groupId> <artifactId>amqp-client </ar ...
- redis简单消息队列
<?php $redis = new Redis(); $redis->connect('127.0.0.1',6379); $redis->flushall(); $redis-& ...
- Redis使用总结(3):实现简单的消息队列
参考Redis实现简单消息队列 Redis提供了两种方式来作消息队列.一个是使用生产者消费模式模式,另外一个方法就是发布订阅者模式.前者会让一个或者多个客户端监听消息队列,一旦消息到达,消费者马上消费 ...
- 玩转redis-简单消息队列
使用go语言基于redis写了一个简单的消息队列 源码地址 使用demo redis的 list 非常的灵活,可以从左边或者右边添加元素,当然也以从任意一头读取数据 添加数据和获取数据的操作也是非常简 ...
- PDO和消息队列的一点个人理解
什么是消息队列,百度百科说,···消息队列····是在消息的传输过程中保存消息的容器. 看着网上林林总总的文章,都说是为了应对高并发,处理数据量超级大的一种数据容器,也可以说是利用各种方式,先把数据存 ...
- RocketMQ 消息队列单机部署及使用
转载请注明来源:http://blog.csdn.net/loongshawn/article/details/51086876 相关文章: <RocketMQ 消息队列单机部署及使用> ...
随机推荐
- windows电脑在线生成ios p12证书工具和生成教程
使用hbuilderx开发ios APP的时候,打包APP提示需要IOS的打包证书 而hbuilderx本身是不能生成证书的,因为生成证书需要在苹果开发者中心生成.而在苹果开发者中心生成证书的时候,提 ...
- 使用 yum 安装 nginx
rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm ...
- Vue.js 事件绑定
1.事件监听 v-on:eventName可以简写成@eventName 事件对象:在HTML中,事件参数为$event,但是即使不传递,在回调函数中也可以直接使用event读取 <div id ...
- Cython二进制逆向系列(一) 初识Cython
Cython二进制逆向系列(一) 初识Cython 众所周知,Python类题目最难的一种就是使用Cython工具将py源码转换为二进制文件.此类题目相比于直接由Cpython编译而成的类字节码文 ...
- 题解 ICPC 2019 SH 区域赛 F 树上简单问题
题解 ICPC 2019 SH 区域赛 F 树上简单问题 CF的Gym里没找着 牛客的题目链接 首先这个题多测非常SB, 每次都要清空, 需要特别注意. 树剖应该都会吧, Defad之后也会发博客讲解 ...
- vue中this.$nextTick()
this.$nextTick()是在下一次DOM更新后执行其指定回调函数 this.$nextTick(回调函数) 使用场景:在改变数据后,要对更新后的DOM进行操作时使用
- k8s pod错误的排查步骤和处理方法
查pod kubectl get pod -n amadeus -o wide 查pod日志 kubectl logs -f --timestamps -n amadeus weyo-server-6 ...
- iOS - 利用 UIBezierPath 绘制圆弧
iOS - 利用 UIBezierPath 绘制圆弧 API UIBezierPath 绘制圆弧主要利用以下方法: open func addArc(withCenter center: CGPoin ...
- IOS中的Context Menu
IOS中的Context Menu 通过长按组件或者3D touch方式,周边全部虚化,弹出一个可操作的菜单,并且菜单之间也可以嵌套 IOS13之后已经弃用UIViewControllerPrevie ...
- Qt编写视频监控系统71-外网访问摄像头等设备(获取各种信息及拉流)
一.前言 最近遇到个需求是通过外网接入摄像机或者NVR,通用的做法是将视频流推流到服务器,然后拉取rtmp视频流,这样就多了服务器的要求,而且实现的功能有限比如不能直接用onvif协议对设备获取信息和 ...