Redis發布訂閱模式-1


發布訂閱模式

發布訂閱模式可以說是耳熟能詳了,它是屬於設計模式中的行為模式,最大的好處就是起到解耦的作用,發布者不用關心在消息產生之后需要做什么,發布者只需要在通道里說“我發布了”,不用管有什么業務邏輯需要處理也不用管有多少的邏輯要處理,很簡單明了。

我們平時用來解耦業務的消息隊列就是實現了發布訂閱模式,所以Redis可以在一些情況下做為消息隊列來使用。

還是貼一張圖把(網上盜的),解釋下這種模式。

img


接下來看看在Redis中怎么實現

相關常用命令

PSUBSCRIBE pattern1 pattern2 //訂閱一個或者多個符合給定模式的通道  ? ?* 和 * ?標識一個占位符,*標識多個占位符包括0個 ?*標識一個以上的占位符
PUBLISH channel1 message1   //發布消息到指定的通道
PUNSUBSCRIBE pattern1 pattern2 //退訂一個或者多個符合給定模式的通道,不傳pattern 代表退訂所有
SUBSCRIBE channel1 channel2 //訂閱一個或者多個通道 
UNSUBSCRIBE channel1 channel2 //退訂一個或者多個通道 不傳channel 代表退訂所有

命令不復雜,我們來操作一下吧 首先發送一個命令到a_1的通道中,因為現在沒有訂閱者所以返回了0

1588153340852

我們新開一個客戶端訂閱這個通道,可以看到成功訂閱了,返回了當前客戶端訂閱的通道數量,但是沒有收到在訂閱之前已經發送的消息,所以Redis的發布訂閱的消息是沒有持久化的,這是如果實現消息隊列需要解決的問題

1588153502396

在第一個客戶端發送幾條消息

1588158591832

能看到第二個客戶端接收到了消息

1588169010979


多說一點

  • Redis實例中的發布和訂閱沒有作用域的區分的,就算在不同的db間。比如你在db0中發布了一個消息,在db2中你同樣能夠收到,如果我們要區分不同的環境需要自己對channel命名來區分。
  • 這里需要注意的是,當一個客戶端訂閱成功一個通道之后,該客戶端就不能執行除了訂閱相關(SUBSCRIBE,UNSUBSCRIBE,PSUBSCRIBE,PUNSUBSCRIBE)的命令了,也就是相當於阻塞着一直等着消息。
  • 另外一點特別需要注意的是,我最開始的理解psubscribe只是支持模式匹配,最終的效果應該和subscribe是一樣,也就是說當我執行psubscribe的時候,Redis實例會根據我寫的模式去匹配channel,匹配上就訂閱這個channel,比如"pubscribe a_*" 就應該訂閱所有"a_"開頭的channel,最后訂閱的channel都是落到實際的channel上,比如"a_1,a_2"之類的channel。后來我有思考一個問題,當Redis實例中不存在a開頭的channel,或者后面才有a開頭的channel,我在最開始訂閱 "a_"也是能接收到后面創建的channel中發送的信息
  • 其實Redis對於模式的訂閱和普通的訂閱是分開的,也就是同一個客戶端訂閱了模式a_,又訂閱了a_1,那么你將會收到兩條消息,就算你分別執行psubscribe a_1和subscribe a_1,這同樣是訂閱了兩次,你會收到兩次消息。
  • 我們可以做下測試,在上面的例子中我們已經通過subscribe a_1 訂閱了a_1通道,並成功收到消息,我們再次執行psubscribe a_2 ,並在客戶端1發送消息message5,可以看到我們收到兩條相同的消息,具體原因會在下一節實現原理中。
  • 可以看見我把上面那句話給划掉了,是因為我在不同客戶端測試的時候既然出現了不同的情況,具體原因不太清楚希望有人能解答下。

不同客戶端執行相同命令產生不同的結果?

  1. 首先我用Another RDM的Console來進行訂閱,命令會返回當前客戶端訂閱的通道數量,多次訂閱不會重復訂閱

    1588170587238

  2. 接着在客戶端1中發送消息,命令會返回訂閱的客戶端數量

    1588170664563

  3. 接着在客戶端2中進行模式訂閱,可以看到訂閱的通道數量變成2了,在客戶端1發送消息,數量也變成2,所以我覺得發送信息的命令應該返回的是發送消息的數量

    1588170748596

    1588170814087

  4. 看到這里就已經證明我上面的說的話,但是因為Another沒法監聽的消息,我用redis-cli測試了一遍,然后就發現同樣的命令既然產生不同的效果了。如下圖,能看到當我psubscribe的時候沒有輸出東西,當我在客戶端1發送消息的時候也只收到一條,而且客戶端1顯示消息數量也是3。而不是預想中的4。具體原因我也想不出來了。。希望大神解答。

    1588171030388

1588171114810

后來在官網看到了說法

Messages matching both a pattern and a channel subscription

A client may receive a single message multiple times if it's subscribed to multiple patterns matching a published message, or if it is subscribed to both patterns and channels matching the message. Like in the following example:

SUBSCRIBE foo
PSUBSCRIBE f*

In the above example, if a message is sent to channel foo, the client will receive two messages: one of type messageand one of type pmessage.

也就是印證了我最開始的想法。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM