redis的發佈訂閱模式

發佈訂閱模式:就是一個發佈者發佈消息,多個訂閱者進行消息的訂閱,目的是爲了消息的傳送,

1.發佈訂閱模式的結構

   主要包含三個部分:發佈者,訂閱者和Channel。


這裏寫圖片描述

 

結合上圖和消息中間件,可以將channel和消息中間件中的topic主題對應起來

2. Redis發佈訂閱功能

命令 用例和描述
subscribe subscribe channel [channel …] 訂閱一個或多個頻道
unsubscribe unsubscribe [channel [channel …]] 退訂頻道,如果沒有指定頻道,則退訂所有的頻道
publish publish channel message 給指定的頻道發消息
psubscribe psubscribe pattern [pattern …] 訂閱給定模式相匹配的所有頻道
punsubscribe punsubscribe [pattern [pattern …]] 退訂給定的模式,如果沒有指定模式,則退訂所有模式

(1)發送消息 
Redis採用PUBLISH命令發送消息,其返回值爲接收到該消息的訂閱者的數量。 
這裏寫圖片描述 
(2)訂閱某個頻道 
Redis採用SUBSCRIBE命令訂閱某個頻道,其返回值包括客戶端訂閱的頻道,目前已訂閱的頻道數量,以及接收到的消息,其中subscribe表示已經成功訂閱了某個頻道。 
這裏寫圖片描述 

上圖 指令說明 subscribe first second 表示訂閱者訂閱 訂閱的 channel,這裏可以多個,因爲語法中這個是channel[]類型

返回的話,一般是三行式:第一行:subscribe 作爲一種迴應告訴是訂閱,第二行 代表訂閱的內容,消息,第三個 訂閱的個數
(3)模式匹配 
模式匹配功能允許客戶端訂閱符合某個模式的頻道,Redis採用PSUBSCRIBE訂閱符合某個模式所有頻道,用“”表示模式,“”可以被任意值代替。 
這裏寫圖片描述 
假設客戶端同時訂閱了某種模式和符合該模式的某個頻道,那麼發送給這個頻道的消息將被客戶端接收到兩次,只不過這兩條消息的類型不同,一個是message類型,一個是pmessage類型,但其內容相同。 
(4)取消訂閱 
Redis採用UNSUBSCRIBE和PUNSUBSCRIBE命令取消訂閱,其返回值與訂閱類似。 
由於Redis的訂閱操作是阻塞式的,因此一旦客戶端訂閱了某個頻道或模式,就將會一直處於訂閱狀態直到退出。在SUBSCRIBE,PSUBSCRIBE,UNSUBSCRIBE和PUNSUBSCRIBE命令中,其返回值都包含了該客戶端當前訂閱的頻道和模式的數量,當這個數量變爲0時,該客戶端會自動退出訂閱狀態

3. redis 發佈訂閱的原理

每個 Redis 服務器進程都維持着一個表示服務器狀態的 redis.h/redisServer 結構, 結構的 pubsub_channels 屬性是一個字典, 

其中,字典的鍵爲正在被訂閱的頻道, 而字典的值則是一個鏈表, 鏈表中保存了所有訂閱這個頻道的客戶端。

比如說,在下圖展示的這個 pubsub_channels 示例中, client2 、 client5 和 client1 就訂閱了 channel1 , 而其他頻道也分別被別的客戶端所訂閱:

當客戶端調用 SUBSCRIBE 命令時, 程序就將客戶端和要訂閱的頻道在 pubsub_channels 字典中關聯起來。

舉個例子,如果客戶端 client10086 執行命令 SUBSCRIBE channel1 channel2 channel3 ,那麼前面展示的 pubsub_channels 將變成下面這個樣子:

發送信息到頻道

瞭解了 pubsub_channels 字典的結構之後, 解釋 PUBLISH 命令的實現就非常簡單了: 當調用 PUBLISH channel message 命令, 程序首先根據 channel 定位到字典的鍵, 然後將信息發送給字典值鏈表中的所有客戶端。

比如說,對於以下這個 pubsub_channels 實例, 如果某個客戶端執行命令 PUBLISH channel1 "hello moto" ,那麼 client2 、 client5 和 client1 三個客戶端都將接收到 "hello moto" 信息:

退訂頻道

使用 UNSUBSCRIBE 命令可以退訂指定的頻道, 這個命令執行的是訂閱的反操作: 它從 pubsub_channels 字典的給定頻道, 刪除關於當前客戶端的信息, 這樣被退訂頻道的信息就不會再發送給這個客戶端。

4. redis的發佈訂閱和ActiveMQ的區別

  • (1)ActiveMQ支持多種消息協議,包括AMQP,MQTT,Stomp等,並且支持JMS規範,但Redis沒有提供對這些協議的支持;
  • (2)ActiveMQ提供持久化功能,但Redis無法對消息持久化存儲,一旦消息被髮送,如果沒有訂閱者接收,那麼消息就會丟失;
  • (3)ActiveMQ提供了消息傳輸保障,當客戶端連接超時或事務回滾等情況發生時,消息會被重新發送給客戶端,Redis沒有提供消息傳輸保障

參照博客:https://www.jianshu.com/p/e67876454c09

https://blog.csdn.net/fly910905/article/details/78495971

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章