队列操作

简单队列

利用List数据结构可以实现简单的队列,在于使用List提供插入和移除api来完成简单队列操作;

准备数据

获取数据

后入先出

使用redis提供的apiLPOP可以从队列左边获取数据,也就是从队列的头部获取到最后插入的数据,也可以使用BLPOP设置超时时间,从而做到等待数据写入;

先入先出

与上面的一样,只是把获取数据的方向改成另一边,使用RPOP可以从队列右边获取数据,也就是从队列的尾部获取到最先插入的数据,也可以使用BRPOP设置超时时间,从而做到等待数据写入;

等待

使用BLPOPBRPOP可以移除并获取列表头部/尾部获取第一个元素;如果把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中对应的BLPOPBRPOP命令,但是可以使用发布订阅模式实现;

发布订阅

生产者

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实现简单消息队列的更多相关文章

  1. simple简单消息队列

    一:介绍 1.优缺点 简单,但是耦合性较高. 这种模式是生产者与消费者一一对应,就是一个产生者,有一个消费者来消费. 如果,多个消费者想消费一个队列中的消息就不适合了.这种情况在后面会接着介绍. 2. ...

  2. Redis实现简单消息队列

    http://www.jianshu.com/p/9c04890615ba 任务异步化 打开浏览器,输入地址,按下回车,打开了页面.于是一个HTTP请求(request)就由客户端发送到服务器,服务器 ...

  3. 用 Redis 实现 PHP 的简单消息队列

    参考:PHP高级编程之消息队列 消息队列就是在消息的传输过程中,可以保存消息的容器. 常见用途: 存储转发:异步处理耗时的任务 分布式事务:多个消费者消费同一个消息队列 应对高并发:通过消息队列保存任 ...

  4. redis(五)---- 简单消息队列

    消息队列一个消息的链表,是一个异步处理的数据处理引擎.不仅能够提高系统的负荷,还能够改善因网络阻塞导致的数据缺失.一般用于邮件发送.手机短信发送,数据表单提交.图片生成.视频转换.日志储存等. red ...

  5. RabbitMq(2) 简单消息队列

    <dependency> <groupId>com.rabbitmq</groupId> <artifactId>amqp-client </ar ...

  6. redis简单消息队列

    <?php $redis = new Redis(); $redis->connect('127.0.0.1',6379); $redis->flushall(); $redis-& ...

  7. Redis使用总结(3):实现简单的消息队列

    参考Redis实现简单消息队列 Redis提供了两种方式来作消息队列.一个是使用生产者消费模式模式,另外一个方法就是发布订阅者模式.前者会让一个或者多个客户端监听消息队列,一旦消息到达,消费者马上消费 ...

  8. 玩转redis-简单消息队列

    使用go语言基于redis写了一个简单的消息队列 源码地址 使用demo redis的 list 非常的灵活,可以从左边或者右边添加元素,当然也以从任意一头读取数据 添加数据和获取数据的操作也是非常简 ...

  9. PDO和消息队列的一点个人理解

    什么是消息队列,百度百科说,···消息队列····是在消息的传输过程中保存消息的容器. 看着网上林林总总的文章,都说是为了应对高并发,处理数据量超级大的一种数据容器,也可以说是利用各种方式,先把数据存 ...

  10. RocketMQ 消息队列单机部署及使用

    转载请注明来源:http://blog.csdn.net/loongshawn/article/details/51086876 相关文章: <RocketMQ 消息队列单机部署及使用> ...

随机推荐

  1. Linux命令之ncdu

    简介 Ncdu - NCurses Disk Usage Ncdu 是一个带有 ncurses 接口的磁盘使用分析器. 它旨在在您没有完整图形设置可用的远程服务器上查找空间占用,但即使在常规桌面系统上 ...

  2. Blazor 组件库 BootstrapBlazor 中Tag组件介绍

    Tag组件的样子 Tag组件的介绍 Tag组件是一个非常简单的组件. <Tag Icon="fa fa-fw fa-check-circle" Color="Col ...

  3. Java Class 文件中Method的存储

    class文件是java编译后的文件类型.其代表一个类,其有专门的存储格式.其中会存放数据也会存放方法,而所谓的方法存放就是将方法中的调用都转换成java字节码指令.所方法调用从机器的角度看就是对于寄 ...

  4. Mybatis【9】-- Mybatis占位符#{}和拼接符${}有什么区别?

    代码直接放在Github仓库[https://github.com/Damaer/Mybatis-Learning ],可直接运行,就不占篇幅了. 目录 1.#{}占位符 2.${}拼接符 3.#{} ...

  5. vue使用高德地图初始化坑

    使用的时候有时候会报除Amap没有定义之外的错如 TypeError: v.w.uh is not a constructor Uncaught TypeError: Cannot read prop ...

  6. 如何将java私有库(jar)提交至公服/公共仓库(central repository)-手动版

    如何将java私有库(jar)提交至公服/公共仓库(central repository)-手动版 准备 GunPG(用于asc签名) 项目代码(建议是maven结构的) sonatype账号(htt ...

  7. VS Code 变身小霸王游戏机!

    在韩老师的<Visual Studio Code 权威指南>一书中,我向大家推荐了许多好用的插件,其中也不乏许多摸鱼插件,刷知乎.炒股票.看电影.听音乐.追番.看小说,一应俱全. 今天,就 ...

  8. Springboot-actuator的常用endpoint的使用说明

    目的 监控并管理应用程序监控:让我们去发现和了解程序的运行状况各种指标管理:比如说通过Actuator去做一个shutdown功能,通过访问一个特定的url去操作,默认是不开启的,另外 还可以在运行的 ...

  9. nginx如何配置代理转发

    Nginx是个厉害的服务器,可以配置多个服务器,一个server就是一个服务器server {      listen       80;      server_name  *.yourdomain ...

  10. Qt/C++推流程序(视频文件/视频流/摄像头/桌面转成流媒体rtmp+hls+webrtc)可在网页和播放器远程观看

    一.前言说明 推流直播就是把采集阶段封包好的内容传输到服务器的过程.其实就是将现场的视频信号从手机端,电脑端,摄影机端打包传到服务器的过程."推流"对网络要求比较高,如果网络不稳定 ...