Redis的發(fā)布與訂閱

  1. 什么是發(fā)布訂閱
  • Redis發(fā)布訂閱(pub/sub)是一種消息通訊模式,發(fā)送者(pub)發(fā)送消息,訂閱者(sub)接收消息。
  • Redis客戶端可以通過廣播的方式將消息(message)同時(shí)發(fā)送給可能存在的多個(gè)客戶端,并且發(fā)送消息的客戶端不需要知道接受消息的客戶端的具體信息。(發(fā)布消息的客戶端和接收消息的客戶端兩者之間沒有直接聯(lián)系)
  • 客戶端可以訂閱(subscribe)任意數(shù)量的頻道(channel),每當(dāng)有新消息被發(fā)送到訂閱的頻道時(shí),信息就會(huì)被發(fā)送給所有訂閱指定頻道的客戶端。
  • 一個(gè)頻道可以被多個(gè)客戶端訂閱,一個(gè)客戶端也可以訂閱多個(gè)頻道。
  1. 使用場(chǎng)景
  • 實(shí)時(shí)溝通消息系統(tǒng)
  • 微信公眾號(hào)(點(diǎn)擊關(guān)注即訂閱該公眾號(hào),公眾號(hào)發(fā)布博文后,訂閱的用戶就可以監(jiān)聽到)
  • 粉絲關(guān)注
  • 文章推送
  • 電商中,用戶下單成功后向指定頻道發(fā)送消息,下游業(yè)務(wù)訂閱支付結(jié)果處理后續(xù)業(yè)務(wù)。
  1. 圖解
    三個(gè)客戶端分別訂閱channel1和channel2 2個(gè)頻道


    image.png

    發(fā)布者(publisher)向channel1頻道發(fā)送了的消息被channel1的訂閱者client1、client2、client3同時(shí)接收到,發(fā)布者向channel2發(fā)送的消息只能被channel2的訂閱者client2、client3接收到,client1無法接收


    image.png
  2. 命令行實(shí)現(xiàn)

  • 客戶端訂閱channel1頻道(客戶端1)
# 訂閱1個(gè)或者多個(gè)頻道subscribe channel  [channel ... ]
subscribe channel1
image.png
  • 給channel1頻道發(fā)送消息 hello(客戶端2)
publish channel hello
# 返回頻道訂閱者的數(shù)量
image.png
  • 打開客戶端1可以看見發(fā)送的消息
image.png
  • 退訂頻道
unsubscribe  channel  [channel ... ]
  • 查看訂閱與發(fā)布系統(tǒng)的狀態(tài)
pubsub channels [argument  [atgument ...] ]
  1. 為什么要使用發(fā)布和訂閱
  • 消息發(fā)送訂閱功能很多大廠使用的是kafka、RabbitMQ、ActiveMQ、RocketMQ等消息隊(duì)列,redis的發(fā)布訂閱比較前者相對(duì)輕量,對(duì)于數(shù)據(jù)安全性要求不高的公司可以直接使用
  • redis的List數(shù)據(jù)結(jié)構(gòu)提供了blpop、brpop命令結(jié)合rpush、lpush可以實(shí)現(xiàn)消息隊(duì)列機(jī)制,可以基于雙端鏈表實(shí)現(xiàn)消息的發(fā)布與訂閱(比較笨重,不如直接使用發(fā)布訂閱功能)
  • 不支持一對(duì)多的消息發(fā)送
  • 如果生產(chǎn)者的速度遠(yuǎn)遠(yuǎn)大于消費(fèi)者,容易堆積大量未消費(fèi)的信息
  • 雙端隊(duì)列只能有一個(gè)或者多個(gè)消費(fèi)者輪著去消費(fèi),但是不能將消息同時(shí)發(fā)送給其他消費(fèi)者
  • redis發(fā)布訂閱模式,生產(chǎn)者生產(chǎn)完消息直接通過頻道分發(fā)消息給訂閱了該頻道的所有消費(fèi)者
  1. 兩種實(shí)現(xiàn)模式
  • 上述4為“基于頻道”的發(fā)布訂閱模式
  • 基于模式配(pattern)的發(fā)布訂閱模式
  • 訂閱一個(gè)或者多個(gè)符合給定模式的頻道,每個(gè)模式以作為匹配符;例如cn 匹配所有以cn開頭的頻道
psubscribe pattern1  [pattern...]
# 訂閱者訂閱頻道  訂閱a?和com.*兩種模式的頻道  ?表示一個(gè)占位符 a?表示匹配 aa、ab、ac等a開頭的兩個(gè)字符的頻道
psubscribe a? com.*

# 發(fā)布者發(fā)布消息
publish ahead "hello" ——————(integer 1) 發(fā)布失敗,沒有訂閱者
publish aa "hello"——————(integer 1) 有1個(gè)匹配著
publish com.cn "hello"——————(integer 1) 有1個(gè)匹配著
  • 退訂所有指定模式的頻道,如果pattern未指定則訂閱的所有模式都被退訂
punsubscribe [pattern [pattern ...] ]
  1. 實(shí)現(xiàn)原理
  • 基于頻道模式
  • 由底層字典實(shí)現(xiàn),所有pubsub_channels是一個(gè)字典類型。字典的key為訂閱的頻道,value為一個(gè)鏈表,鏈表中保存了所有訂閱該頻道的客戶端
image.png
  • 基于匹配模式
  • 底層由pubsub_pattern節(jié)點(diǎn)的鏈表實(shí)現(xiàn)
  • 新增一個(gè)pubsub_pattern數(shù)據(jù)結(jié)構(gòu)添加到鏈表的最后尾部,同時(shí)保存客戶端ID
  • 取消訂閱模式:從當(dāng)前的鏈表pubsub_pattern結(jié)構(gòu)中刪除需要取消的pubsub_pattern結(jié)構(gòu)


    image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容