redis可以當(dāng)消息隊(duì)列使用嗎

redis不僅可作為緩存服務(wù)器,還可用作消息隊(duì)列。它的列表類型天生支持用作消息隊(duì)列。

redis可以當(dāng)消息隊(duì)列使用嗎

由于redis的列表是使用雙向鏈表實(shí)現(xiàn)的,保存了頭尾節(jié)點(diǎn),所以在列表頭尾兩邊插取元素都是非??斓?。(推薦學(xué)習(xí):Redis視頻教程

所以可以直接使用Redis的List實(shí)現(xiàn)消息隊(duì)列,只需簡單的兩個(gè)指令lpush和rpop或者rpush和lpop。

但是會(huì)有消息消費(fèi)者有一個(gè)問題存在,即需要不停的調(diào)用rpop方法查看List中是否有待處理消息。每調(diào)用一次都會(huì)發(fā)起一次連接,這會(huì)造成不必要的浪費(fèi)。也許你會(huì)使用Thread.sleep()等方法讓消費(fèi)者線程隔一段時(shí)間再消費(fèi),但這樣做有兩個(gè)問題:

1)、如果生產(chǎn)者速度大于消費(fèi)者消費(fèi)速度,消息隊(duì)列長度會(huì)一直增大,時(shí)間久了會(huì)占用大量內(nèi)存空間。

2)、如果睡眠時(shí)間過長,這樣不能處理一些時(shí)效性的消息,睡眠時(shí)間過短,也會(huì)在連接上造成比較大的開銷。

所以可以使用brpop指令,這個(gè)指令只有在有元素時(shí)才返回,沒有則會(huì)阻塞直到超時(shí)返回NULL,然后可以運(yùn)行Customer,清空控制臺(tái),可以看到程序沒有任何輸出,阻塞在了brpop這兒。然后在打開Redis的客戶端,輸入指令client list,可以查看當(dāng)前有兩個(gè)連接。

Redis除了對(duì)消息隊(duì)列提供支持外,還提供了一組命令用于支持發(fā)布/訂閱模式。

1)發(fā)布

PUBLISH指令可用于發(fā)布一條消息,格式 PUBLISH channel message

返回值表示訂閱了該消息的數(shù)量。

2)訂閱

SUBSCRIBE指令用于接收一條消息,格式 SUBSCRIBE channel

可以看到使用SUBSCRIBE指令后進(jìn)入了訂閱模式,但沒有接收到publish發(fā)送的消息,這是因?yàn)橹挥性谙l(fā)出去前訂閱才會(huì)接收到。在這個(gè)模式下其他指令,只能看到回復(fù)。

回復(fù)分為三種類型:

1、如果為subscribe,第二個(gè)值表示訂閱的頻道,第三個(gè)值表示是第幾個(gè)訂閱的頻道?(理解成序號(hào)?)?

2、如果為message(消息),第二個(gè)值為產(chǎn)生該消息的頻道,第三個(gè)值為消息

3、如果為unsubscribe,第二個(gè)值表示取消訂閱的頻道,第三個(gè)值表示當(dāng)前客戶端的訂閱數(shù)量。

可以使用指令UNSUBSCRIBE退訂,如果不加參數(shù),則會(huì)退訂所有由SUBSCRIBE指令訂閱的頻道。

Redis還支持基于通配符的消息訂閱,使用指令PSUBSCRIBE (pattern subscribe)。

可以看到publish指令返回的是2,而訂閱端這邊接收了兩次消息。這是因?yàn)镻SUBSCRIBE指令可以重復(fù)訂閱頻道。而使用PSUBSCRIBE指令訂閱的頻道也要使用指令PUNSUBSCRIBE指令退訂,該指令無法退訂SUBSCRIBE訂閱的頻道,同理UNSUBSCRIBE也不能退訂PSUBSCRIBE指令訂閱的頻道。同時(shí)PUNSUBSCRIBE指令通配符不會(huì)展開。

總結(jié):

使用Redis的List數(shù)據(jù)結(jié)構(gòu)可以簡單迅速地做一個(gè)消息隊(duì)列,同時(shí)Redis提供的BRPOP和BLPOP等指令解決了頻繁調(diào)用Jedis的rpop和lpop方法造成的資源浪費(fèi)問題。除此之外,Redis提供對(duì)發(fā)布/訂閱模式的指令,可以實(shí)現(xiàn)消息傳遞、進(jìn)程間通信。

更多Redis相關(guān)技術(shù)文章,請(qǐng)?jiān)L問Redis視頻教程欄目進(jìn)行學(xué)習(xí)!

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點(diǎn)贊6 分享