閱讀269 返回首頁    go 阿裏雲 go 技術社區[雲棲]


《Redis官方文檔》發布和訂閱

發布/訂閱(Pub/Sub)

SUBSCRIBE、UNSUBSCRIBE 和 PUBLISH 這三個命令實現了發布/訂閱消息模式(引用自維基百科),發送者(發布者)並不是直接發送它們的消息給指定的接收者(訂閱者),而是將消息發布到特定的消息通道,並且不需要知道訂閱者(如果有的話)的任何信息。訂閱者可以訂閱一個或多個感興趣的消息通道,同時也隻會收到他們感興趣通道的信息,而不用去關心是誰發布的。這種發布者與訂閱者的解耦,使其具備更強的擴展性並得到一個更加動態的網絡拓撲。


例如為了訂閱通道foo和bar,客戶端可以使用通道名稱為參數去調用 SUBSCRIBE 命令:

SUBSCRIBE foo bar

其他客戶端發送到消息到這些通道時,消息會由 Redis 推送到所有訂閱了這些通道的客戶端。

訂閱了一個或多個通道的客戶端就不應該再使用命令,盡管它還能訂閱其他頻道或取消訂閱其他通道。訂閱和取消訂閱的執行結果會以消息的形式返回。所以客戶端能夠解析這互相耦合的消息,其中第一個元素表示消息的類型。訂閱了通道的客戶端上允許使用的命令有 SUBSCRIBE、PSUBSCRIBE、UNSUBSCRIBE、PUNSUBSCRIBE、PING和QUIT。

推送消息的格式

消息是一條含有三個元素的@array-reply。第一個元素是消息的類型:

  • subscribe:意味著我們已經成功訂閱了第二個元素所指的通道。第三個參數表示當前已經訂閱的通道總數。
  • unsubscribe:意味著已經成功的取消了第二個元素所指的通道。第三個參數表示當前訂閱的頻道總數。當最後一個參數是 0 的時候,就表示不再訂閱任何頻道,同時客戶端也可以使用Redis提供的任何命令,因為此時客戶端已經退出發布/訂閱狀態。
  • message:這是某一個客戶端使用 PUBLISH 命令後會收到的操作結果信息。第二個元素是信息來源的頻道,同時第三個參數是真實消息的內容。

數據庫與範圍

Pub/Sub 模式與 KEY 空間無關。它與任何層麵無關,包括數據庫數目。
在 db 10 上進行發布,db 1上的訂閱者也會收到信息。
如果你需要覆蓋某一些類型,把頻道的前綴用一些特定的變量(test,staging,production….)
例如:

01 SUBSCRIBE first second
02 *3
03 $9
04 subscribe
05 $5
06 first
07 :1
08 *3
09 $9
10 subscribe
11 $6
12 second
13 :2

此時,從另一個客戶端上對 second 頻道執行 PUBLISH 命令操作:

1 PUBLISH second Hello

這就是前麵訂閱了頻道的客戶端收到的信息:

1 *3
2 $7
3 message
4 $6
5 second
6 $5
7 Hello

現在客戶端執行無參的 UNSUBSCRIBE 命令來取消自己訂閱的所有頻道:

01 UNSUBSCRIBE
02 *3
03 $11
04 unsubscribe
05 $6
06 second
07 :1
08 *3
09 $11
10 unsubscribe
11 $5
12 first
13 :0

訂閱的模式匹配

Redis 的 Pub/Sub 實現支持模式匹配。客戶端可以用 glob 風格的模式去接收頻道名稱與模式相匹配的所有頻道消息。
例如:執行命令PSUBSCRIBE news.*的客戶端將後收到所有發送到 news.art.figurative,news.music.jazz 等等頻道的信息。所有 glob 風格的模式匹配都是有效的,同時也支持多重通配符。
執行命令PUNSUBSCRIBE news.*的客戶端會取消訂閱頻道名稱與 給定模式(news.*) 相匹配的所有頻道,而其他已經訂閱的頻道不會愛影響。模式匹配訂閱的信息格式是另一種不同的格式:
消息的類型是 pmessage:表示另一個客戶端執行 PUBLISH 命令向頻道發送消息,而頻道符合當前客戶端訂閱的模式匹配。第二個元素就是匹配的模式,第三個元素就是模式匹配到的頻道名稱,最後一個元素就是真正的消息載體。
與係統處理 SUBSCRIBE 和 UNSUBSCRIBE, PSUBSCRIBE 和 PUNSUBSCRIBE 命令一樣,發送的消息類型為 psubscribe 和 punsubscribe ,然後使用 subscribe 和 unsubscribe 一樣的消息格式。

消息同時匹配模式與訂閱的頻道

一個客戶端可能多次收到同一條消息,如果它訂閱的多個模式匹配到了一條發布的消息,或者它訂閱的模式與頻道匹配到了同一條消息。例如:

1 SUBSCRIBE foo
2 PSUBSCRIBE f*

在上麵的例子中,如果一條消息發送到foo頻道,客戶端將會收到兩條消息。一個是 message類型的消息,一種是pmessage類型的消息。

模式匹配下訂閱數的意義

在 subscribe, unsubscribe, psubscribe 和 punsubscribe 等消息類型中,最後一個參數表示仍在訂閱的頻道數。這個數字實際上就是客戶端訂閱的頻道與模式的總數。
所以當客戶端取消訂閱所有頻道和模式時,也就是這個總數值變為 0 時,客戶端將會退出 Pub/Sub 模式。

編程示例

Pieter Noordhuis 提供了一個很好的例子,通過 EventMachine 和 Redis創建了一個多用戶高性能的WEB聊天網站

戶端庫實現提示

由於所有的消息都會有一個訂閱源。(當消息類型為 message 時,訂閱源是一個頻道,當消息類型為 pmessage 時,訂閱源是一個模式)客戶端可以利用一個HASH表將這些訂閱源與回調函數綁定起來,這樣當一個消息被接收後,能在 O(1) 的時間內將消息交給注冊好的回調函數。

轉載自 並發編程網 - ifeve.com

最後更新:2017-05-19 14:33:40

  上一篇:go  數據庫必會必知 之 SQL四種語言:DDL DML DCL TCL
  下一篇:go  《Java8開發指南》翻譯邀請