一般来说,消息队列有两种场景,一种是发布者订阅者模式,一种是生产者消费者模式。利用redis这两种场景的消息队列都能够实现。
定义:

  • 生产者消费者模式:生产者生产消息放到队列里,多个消费者同时监听队列,谁先抢到消息谁就会从队列中取走消息;即对于每个消息只能被最多一个消费者拥有。
  • 发布者订阅者模式:发布者生产消息放到队列里,多个监听队列的消费者都会收到同一份消息;即正常情况下每个消费者收到的消息应该都是一样的。

那么如此多的MQ产品,为什么要使用redis作消息队列呢?以下附上一份总结了别人的一些report或blog的表格,以及当初用来说服整个team的一句结论。

MQ Env. Weight Disadvantage      
RabbitMQ Erlang Heavy Bad scalability;Low speed;    
ZeroMQ C Light difficult for development    
ActiveMQ Java - Low performance      
Redis C - Low performance while enqueuing big data (>= 10k) 

Redis is easy to use and configure since we have experience in Redis, and most importantly, its performance satisfies our requirement.

Then, how to use redis as a MQ?

首先,redis的队列实际在代码逻辑中不需要由我们自己实现,因此一个所谓的 RedisMQ 对象实际是一个 redis key以及对其操作的一些封装。

PubSub Mode:

redis 从 2.0.0 版本开始支持 pub/sub 指令。详情见 http://redis.io/topics/pubsub

实现思想很简单,Publisher调用redis的publish方法往特定的channel发送消息,Subscriber在初始化的时候要subscribe到该channel,一旦有消息就会立即接收。

比较简单的demo可参见:http://shift-alt-ctrl.iteye.com/blog/1867454 ,此链接博客中写得已较详细,本文便不再赘述。

Producer/Consumer Mode:

该方法是借助redis的list结构实现的。

Producer调用redis的lpush往特定key里塞入消息,Consumer调用brpop去不断监听该key。

producer:

 // producer code
String key = "demo:mq:test";
String msg = "hello world";
redisDao.lpush(key, msg);

consumer:

 // consumer code
String key = "demo:mq:test";
while (true) {
// block invoke
List<String> msgs = redisDao.brpop(BLOCK_TIMEOUT, listKey);
if (msgs == null) continue;
String jobMsg = msgs.get(1);
processMsg(jobMsg);
}

当有多个consumers的时候,它会按照brpop调用的顺序分派消息,并非随机。

BLOCK_TIMEOUT不建议设成infinity(有些redis驱动也直接不支持inifinity),我们目前设成30(单位是秒)情况良好。

P.S. 本文时间较久远,适合redis 2的版本,不保证redis自己会不会有其他新特性 ;同时消息队列产品有很多种,这里列的只是早年常用的,近两三年的kafka和阿里的rocketmq也很火,至于怎么选择,一部分是根据数据量,若数据量不大,容错要求不是极高,redis是个高效开发易维护的好选择;如果数据量很大或对消息准确性有一定要求,那应当考虑更成熟的消息队列产品比如kafka等。所以mq的选型并不是本文的重点,本文只是介绍一下基于redis 2.6的mq的简单封装实现。

Redis 做消息队列的更多相关文章

  1. Redis除了做缓存--Redis做消息队列/Redis做分布式锁/Redis做接口限流

    1.用Redis实现消息队列 用命令lpush入队,rpop出队 Long size = jedis.lpush("QueueName", message);//返回存放的数据条数 ...

  2. 程序员过关斩将--redis做消息队列,香吗?

    Redis消息队列 在程序员这个圈子打拼了太多年,见过太多的程序员使用redis,其中一部分喜欢把redis做缓存(cache)使用,其中最典型的当属存储用户session,除此之外,把redis作为 ...

  3. Redis做消息队列

    1.连接从Redis中获取日志文件并存储到ES中 [root@Logstash ~]# vim /usr/local/logstash/config/redis.conf input {     be ...

  4. 使用Redis做消息队列

    基于内存的单线程数据库,使Redis的线程安全性极高.而Redis的双向链表数据类型(List)天生就可作为消息队列存储消息. 在这里就不说消息队列的等等一些优点.但是补充一下Redis的List类型 ...

  5. RabbitMQ跟Redis做消息队列的区别

    区别 https://www.zhihu.com/question/20795043 https://blog.csdn.net/dd18709200301/article/details/79077 ...

  6. Redis做消息队列文章两篇

    介绍:http://www.cnblogs.com/lhfcws/p/3732535.html 具体做法:http://shift-alt-ctrl.iteye.com/blog/1867454 另外 ...

  7. 使用Redis Stream来做消息队列和在Asp.Net Core中的实现

    写在前面 我一直以来使用redis的时候,很多低烈度需求(并发要求不是很高)需要用到消息队列的时候,在项目本身已经使用了Redis的情况下都想直接用Redis来做消息队列,而不想引入新的服务,kafk ...

  8. PHP使用Redis实现消息队列

    消息队列可以使用MySQL来实现,可以参考博客PHP使用MySQL实现消息队列,虽然用MySQL可以实现,但是一般不这么用,因为MySQL的数据都存在硬盘中,而从硬盘中对MySQL的操作,I/O花费的 ...

  9. rabbitmq和redis用作消息队列的区别

    将redis发布订阅模式用做消息队列和rabbitmq的区别: 可靠性redis :没有相应的机制保证消息的可靠消费,如果发布者发布一条消息,而没有对应的订阅者的话,这条消息将丢失,不会存在内存中:r ...

随机推荐

  1. CFURLCreateStringByAddingPercentEscapes与CFURLCreateStringByReplacingPercentEscapesUsingEncoding

    iOS中访问HTTP资源需要对URL进行Encode才能正确访问. OC中有方法: - (NSString *)stringByAddingPercentEscapesUsingEncoding:(N ...

  2. cron 任务

    相关文件 /etc/crontab /etc/cron.deny 设置哪个用户有权限运行 cron 任务 /var/spool/cron/root /var/spool/cron/user /var/ ...

  3. url带#号,微信支付那些坑

    现在前端很多框架的前端路由都带#号,主要为了做到无刷新跳转页面. 在微信公众号做微信支付时,配置的支付路径比如是http://www.eee.com/#/order,在调微信支付的方法时错误信息是'U ...

  4. CSS网页制作常用标签

    做了一个简单的网页,从布局到加内容,遇到了很多小问题.很多标签和属性都不会用或者忘记了.所以以此记录一下. 一.如何将边框四角变圆?(或做一个圆形) 顾名思义,如果要更改边框的角需要用到边框(bord ...

  5. GroupBy(..)的四种声明方式的理解及调用

    这里我们以 List<Student> studs作为 source,但是注意,studs中的学生可以是分别属于不同的班级和年级 先看GroupBy的第一种声明: public stati ...

  6. Guava学习笔记(一)概览

    Guava是谷歌开源的一套Java开发类库,以简洁的编程风格著称,提供了很多实用的工具类, 在之前的工作中应用过Collections API和Guava提供的Cache,不过对Guava没有一个系统 ...

  7. SQL Server 2012 开发新功能 序列对象(Sequence)(转)

    转载链接:http://www.cnblogs.com/zhangyoushugz/archive/2012/11/09/2762720.html 众所周知,在之前的sqlserver版本中,一般采用 ...

  8. 【Java EE 学习 69 下】【数据采集系统第一天】【实体类分析和Base类书写】

    之前SSH框架已经搭建完毕,现在进行实体类的分析和Base类的书写.Base类是抽象类,专门用于继承. 一.实体类关系分析 既然是数据采集系统,首先调查实体(Survey)是一定要有的,一个调查有多个 ...

  9. 关于Knockout的开始

    最近看了汤姆大叔的Knockout,感到MVVM的神奇,也许这就是以后编程的方式,最直观的感觉就是层次更分明了. 绑定,模型转换,监控,在我来说,这算是编程上的一个转变,在以后我做不定期的更新一些MV ...

  10. OpenCv图像裁剪指点区域_roi

    两种方式Range和ROI #include <opencv2/opencv.hpp> using namespace std; using namespace cv; void test ...