標籤:
一般來說,訊息佇列有兩種情境,一種是發行者訂閱者模式,一種是生產者消費者模式。利用redis這兩種情境的訊息佇列都能夠實現。
生產者消費者模式:生產者生產訊息放到隊列裡,多個消費者同時監聽隊列,誰先搶到訊息誰就會從隊列中取走訊息;即對於每個訊息只能被最多一個消費者擁有;
發行者訂閱者模式:發行者生產訊息放到隊列裡,多個監聽隊列的消費者都會收到同一份訊息;即正常情況下每個消費者收到的訊息應該都是一樣的;
對應的使用情境包括:A系統向隊列中存放資料;B系統在隊列中取資料;
1、redis隊列模式:可以實現B系統不線上狀態下,A系統向隊列中存資料,當B系統上線後,可以手動去取隊列中的資料;
2、redis訂閱模式:可以實現A系統向隊列中存資料,當B系統訂閱了此隊列並且線上時,可以自動監聽此隊列去取資料,但之前不線上時的資料無法擷取;
一、Producer/Consumer Mode
該方法是藉助redis的list結構實現的。Producer調用redis的lpush往特定key裡塞入訊息,Consumer調用brpop去不斷監聽該key。
Producer:
1 // producer code2 String key = "demo:mq:test";3 String msg = "hello world";4 redisDao.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(單位是秒)情況良好。
二、Pub/Sub 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
1、Redis訊息的發布與訂閱
Redis的Subscribe命令可以讓客訂閱任意數量的頻道,每當有新資訊發送到被訂閱的頻道時, 資訊就會被發送給所有訂閱指定頻道的用戶端。作為例子,展示了頻道channe11, 以及訂閱這個頻道的三個用戶端:client2、client5和client1之間的關係:
當有新訊息通過 Publish命令發送給頻道channe11時, 這個訊息就會被發送給訂閱它的三個用戶端:
訂閱bar頻道。格式:Subscribe name1 name2
成功訂閱回複,分別對應訂閱類型、訂閱頻道、訂閱數量。
127.0.0.1:6379> SUBSCRIBE barReading messages... (press Ctrl-C to quit)1) "subscribe"2) "bar"3) (integer) 1
重新啟一發行者client,發送訊息。格式:publish channelName Message
#對有一個訂閱者的頻道發送資訊
127.0.0.1:6379> publish bar val(integer) 1
#對沒有訂閱者的頻道發送資訊
127.0.0.1:6379> publish bar "can any body hear me?"
(integer) 0
訂閱client回複,分別對應訊息類型,頻道,訊息。
1) "message"2) "bar"3) "val"
詳情請參見:http://www.cnblogs.com/mushroom/p/4470006.html
http://redis.readthedocs.org/en/2.4/pub_sub.html
2、鍵空間通知(Keyspace notifications)
在訂閱頻道之前,設定set notify-keyspace-events KEA參數,然後再運行Subscribe name1 name2訂閱頻道。
此時,當有某一指定鍵更新時會發送訊息給訂閱者
請參見:http://redis.io/topics/notifications
http://blog.csdn.net/chaijunkun/article/details/27361453
Redis訊息佇列