您好,登錄后才能下訂單哦!
這篇文章主要講解了“Redis發布/訂閱模式實例分析”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Redis發布/訂閱模式實例分析”吧!
發布訂閱(pub/sub)是一種消息通信模式,主要的目的是解耦消息發布者和消息訂閱者之間的耦合,這點和設計模式中的觀察者模式比較相似。pub /sub不僅僅解決發布者和訂閱者直接代碼級別耦合也解決兩者在物理部署上的耦合。redis作為一個pub/sub server,在訂閱者和發布者之間起到了消息路由的功能。訂閱者可以通過subscribe和psubscribe命令向redis server訂閱自己感興趣的消息類型,redis將消息類型稱為通道(channel)。當發布者通過publish命令向redis server發送特定類型的消息時。訂閱該消息類型的全部client都會收到此消息。這里消息的傳遞是多對多的。一個client可以訂閱多個 channel,也可以向多個channel發送消息。
下面還是從基本命令入手:
PSUBSCRIBE pattern [pattern ...] #訂閱一個或多個符合給定模式的頻道;PUBSUB subcommand [argument [argument ...]] #查看訂閱與發布系統狀態;PUBLISH channel message #將信息發送到指定的頻道;PUNSUBSCRIBE [pattern [pattern ...]] #退訂所有給定模式的頻道;SUBSCRIBE channel [channel ...] #訂閱給定的一個或多個頻道的信息;UNSUBSCRIBE [channel [channel ...]] #指退訂給定的頻道;
從redis手冊上面可以看到,其實“發布、訂閱”模式才區區6個命令,下面聽我一一解說下
SUBSCRIBE
訂閱給定的一個或多個頻道的信息。
SUBSCRIBE channel [channel ...]
從上面的官方解釋上來看,它的玩法有一點像現實生活中我們聽收音機一個道理,要想聽收音機,我們要做什么?肯定就是調頻啦,只有在正確的頻道上面,我們才能聽得到好聽的節目,所以說subscribe首先要訂閱一個頻道(channel),下面我舉個例子,開兩個client,分別訂閱著msg這個頻道,比如下面這樣:
root@localhost:~ # redis-cli -p 6379127.0.0.1:6379> SUBSCRIBE msg Reading messages... (press Ctrl-C to quit) 1) "subscribe"2) "msg"3) (integer) 1 root@localhost:~ # redis-cli -p 6379127.0.0.1:6379> SUBSCRIBE msg Reading messages... (press Ctrl-C to quit) 1) "subscribe"2) "msg"3) (integer) 1
SUBSCRIBE還可以訂閱多個頻道,這樣一來它接收到的信息就可能來自多個頻道。
PUBLISH
到現在為止,這兩個subscibe都在監視著msg這個頻道,接下來,如果msg頻道有消息傳出,必定會被subscribe接收到,我們還是先看看redis手冊上怎么用這個命令。
將信息message發送到指定的頻道channel。
PUBLISH channel message
如下演示:
看到么有,publish在msg這個頻道上面發送消息后,被subscribe監視到了,然后就被分別打印輸出了,好了,到現在為止,最基本的發布訂閱模式就是這樣,是不是很簡單哈。其實呢??? 也就是這么簡單吶,但是呢,有時候我們還有這樣一個需求,就是我能不能模糊匹配key呢?舉了例子,就是要求訂閱china為前綴的所有頻道,如果這樣也可以做到的話,那確實是很牛逼啦。。。我要是回答的話,當然啦,強大的Redis自然會做到這一點,它提供了的命令就是:PSUBSCRIBE。
PSUBSCRIBE
訂閱一個或多個符合給定模式的頻道,每個模式以作為匹配符,比如it匹配所有以it開頭的頻道(it.news、it.blog、it.tweets等等),news.*匹配所有以news.開頭的頻道(news.it、 news.global.today 等等),諸如此類。
PSUBSCRIBE pattern [pattern ...]
看到上面的解釋,你心里可能就在想,這不就是正則匹配么。。。而且前綴”P”就是Pattern的意思,對吧,接下來我就訂閱一下所有china為前綴的channel。
當然,PSUBSCRIBE 也可以接受多個參數,從而匹配多種模式。看完一個小例子后應該對pub/sub功能有了一個感性的認識,需要注意的是當一個連接通過subscribe或者psubscribe訂閱通道后就進入訂閱模式。在這種模式除了再訂閱額外的通道或者用unsubscribe或者punsubscribe命令退出訂閱模式,就不能再發送其他命令。另外使用 psubscribe命令訂閱多個通配符通道,如果一個消息匹配上了多個通道模式的話,會多次收到同一個消息。
Redis的pub/sub還是有點太單薄(實現才用150行代碼)。在安全,認證,可靠性這方便都沒有太多支持。
當一個客戶端通過 PUBLISH 命令向訂閱者發送信息的時候,我們稱這個客戶端為發布者(publisher)。
而當一個客戶端使用 SUBSCRIBE 或者 PSUBSCRIBE 命令接收信息的時候,我們稱這個客戶端為訂閱者(subscriber)。
為了解耦發布者(publisher)和訂閱者(subscriber)之間的關系,Redis 使用了 channel (頻道)作為兩者的中介 —— 發布者將信息直接發布給 channel ,而 channel 負責將信息發送給適當的訂閱者,發布者和訂閱者之間沒有相互關系,也不知道對方的存在:
知道了發布和訂閱的機制之后,接下來就可以開始研究具體的實現了,我們從Redis的訂閱命令開始說起。
前面說到,Redis將所有接受和發送信息的任務交給channel來進行,而所有channel的信息就儲存在redisServer這個結構中:
struct redisServer { // 省略 ... dict *pubsub_channels; // Map channels to list of subscribed clients // 省略 ... };
pubsub_channels是一個字典,字典的鍵就是一個個channel,而字典的值則是一個鏈表,鏈表中保存了所有訂閱這個channel的客戶端。
舉個例子,如果在一個 redisServer 實例中,有一個叫做 news 的頻道,這個頻道同時被client_123 和 client_456 兩個客戶端訂閱,那么這個 redisServer 結構看起來應該是這樣子:
可以看出,實現SUBSCRIBE命令的關鍵,就是將客戶端添加到給定channel的訂閱鏈表中。
除了直接訂閱給定channel外,還可以使用PSUBSCRIBE訂閱一個模式(pattern),訂閱一個模式等同于訂閱所有匹配這個模式的channel 。
和redisServer.pubsub_channels屬性類似,redisServer.pubsub_patterns屬性用于保存所有被訂閱的模式,和pubsub_channels不同的是, pubsub_patterns是一個鏈表(而不是字典):
struct redisServer { // 省略 ... list *pubsub_patterns; // A list of pubsub_patterns // 省略 ... };
pubsub_patterns 的每一個節點都是一個 pubsubPattern 結構的實例,它保存了被訂閱的模式,以及訂閱這個模式的客戶客戶端:
typedef struct pubsubPattern { redisClient *client; robj *pattern; } pubsubPattern;
舉個例子,假設在一個 redisServer 實例中,有一個叫做 news.* 的模式同時被客戶端client_789 和 client_999 訂閱,那么這個 redisServer 結構看起來應該是這樣子:
現在可以知道,實現PSUBSCRIBE命令的關鍵,就是將客戶端和訂閱的模式添加到redisServer.pubsub_patterns當中。
感謝各位的閱讀,以上就是“Redis發布/訂閱模式實例分析”的內容了,經過本文的學習后,相信大家對Redis發布/訂閱模式實例分析這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。