redis作消息隊列的兩種方式

通常來講,消息隊列有兩種場景,一種是發佈者訂閱者模式,一種是生產者消費者模式。利用redis這兩種場景的消息隊列都可以實現。
定義:html

  • 生產者消費者模式:生產者生產消息放到隊列裏,多個消費者同時監聽隊列,誰先搶到消息誰就會從隊列中取走消息;即對於每一個消息只能被最多一個消費者擁有。
  • 發佈者訂閱者模式:發佈者生產消息放到隊列裏,多個監聽隊列的消費者都會收到同一份消息;即正常狀況下每一個消費者收到的消息應該都是同樣的。

 

那麼如此多的MQ產品,爲何要使用redis做消息隊列呢?如下附上一份總結了別人的一些report或blog的表格,以及當初用來講服整個team的一句結論。redis

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.
 ui

Then, how to use redis as a MQ?spa

 

首先,redis的隊列實際在代碼邏輯中不須要由咱們本身實現,所以一個所謂的 RedisMQ 對象實際是一個 redis key以及對其操做的一些封裝。scala

 

PubSub Mode:code

redis 從 2.0.0 版本開始支持 pub/sub 指令。詳情見 http://redis.io/topics/pubsuborm

實現思想很簡單,Publisher調用redis的publish方法往特定的channel發送消息,Subscriber在初始化的時候要subscribe到該channel,一旦有消息就會當即接收。htm

比較簡單的demo可參見:http://shift-alt-ctrl.iteye.com/blog/1867454 ,此連接博客中寫得已較詳細,本文便再也不贅述。對象

 

Producer/Consumer Mode:blog

該方法是藉助redis的list結構實現的。

Producer調用redis的lpush往特定key裏塞入消息,Consumer調用brpop去不斷監聽該key。

producer:

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

consumer:

複製代碼

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

複製代碼

當有多個consumers的時候,它會按照brpop調用的順序分派消息,並不是隨機。

BLOCK_TIMEOUT不建議設成infinity(有些redis驅動也直接不支持inifinity),咱們目前設成30(單位是秒)狀況良好。

相關文章
相關標籤/搜索