歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Redis學習筆記之發布訂閱

Redis學習筆記之發布訂閱

日期:2017/2/28 15:54:33   编辑:Linux教程
發布訂閱(pub/sub)是一種消息通信模式,主要的目的是解耦消息發布者和消息訂閱者之間的耦合,這點和設計模式中的觀察者模式比較相似。pub /sub不僅僅解決發布者和訂閱者直接代碼級別耦合也解決兩者在物理部署上的耦合。redis作為一個pub/sub server,在訂閱者和發布者之間起到了消息路由的功能。訂閱者可以通過subscribe和psubscribe命令向redis server訂閱自己感興趣的消息類型,redis將消息類型稱為通道(channel)。當發布者通過publish命令向redis server發送特定類型的消息時。訂閱該消息類型的全部client都會收到此消息。這裡消息的傳遞是多對多的。一個client可以訂閱多個 channel,也可以向多個channel發送消息。

下面做個實驗。這裡使用兩個不同的client一個是redis自帶的redis-cli另一個是用java寫的簡單的client。代碼如下
import java.net.*;
import java.io.*;
public class PubSubTest {
public static void main(String[] args) {
String cmd = args[0]+"\r\n";
try {
Socket socket = new Socket("192.168.56.55",6379);
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
out.write(cmd.getBytes()); //發送訂閱命令
byte[] buffer = new byte[1024];
while (true) {
int readCount = in.read(buffer);
System.out.write(buffer, 0, readCount);
System.out.println("--------------------------------------");
}
} catch (Exception e) {
}
}
}

代碼就是簡單的從命令行讀取傳過來的訂閱命令,然後通過一個socket連接發送給redis server,然後進入while循環一直讀取redis server傳過來訂閱的消息。並打印到控制台

1 首先編譯並運行此java程序(我是win7下面運行的)
D:\>javac PubSubTest.java
D:\>java PubSubTest "subscribe news.share news.blog"
*3
$9
subscribe
$10
news.share
:1

*3
$9
subscribe
$9
news.blog
:2
--------------------------------------
2 啟動redis-cli
redis> psubscribe news.*
Reading messages... (press Ctrl-c to quit)
1. "psubscribe"
2. "news.*"
3. (integer) 1

3 再啟動一個redis-cli用來發布兩條消息
redis> publish news.share "share a link http://www.google.com"
(integer) 2
redis> publish news.blog "I post a blog"
(integer) 2

4.查看兩個訂閱client的輸出
此時java client打印如下內容
*3
$7
message
$10
news.share
$34
share a link http://www.google.com
--------------------------------------
*3
$7
message
$9
news.blog
$13
I post a blog
--------------------------------------
另一個redis-cli輸出如下
1. "pmessage"
2. "news.*"
3. "news.share"
4. "share a link http://www.google.com"

1. "pmessage"
2. "news.*"
3. "news.blog"
4. "I post a blog"


分析下
java client使用subscribe命令訂閱news.share和news.blog兩個通道,然後立即收到server返回的訂閱成功消息,可以看出 redis的協議是文本類型的,這裡不解釋具體協議內容了,可以參考http://redis.io/topics/protocol。這個報文內容有兩部分,第一部分表示該socket連接上使用 subscribe訂閱news.share成功後,此連接訂閱通道數為1,後一部分表示使用subscribe訂閱news.blog成功後,該連接訂 閱通道總數為2。

redis client使用psubscribe訂閱了一個使用通配符的通道(*表示任意字符串),此訂閱會收到所有與news.*匹配的通道消息。redis- cli打印到控制台的訂閱成功消息表示使用psubscribe命令訂閱news.*成功後,連接訂閱通道總數為1。

當我們在一個client使用publish 向news.share和news.blog通道發出兩個消息後。redis返回的(integer) 2表示有兩個連接收到了此消息。通過觀察兩個訂閱者的輸出可以驗證。具體格式不解釋了,都比較簡單。

看 完一個小例子後應該對pub/sub功能有了一個感性的認識。需要注意的是當一個連接通過subscribe或者psubscribe訂閱通道後就進入訂 閱模式。在這種模式除了再訂閱額外的通道或者用unsubscribe或者punsubscribe命令退出訂閱模式,就不能再發送其他命令。另外使用 psubscribe命令訂閱多個通配符通道,如果一個消息匹配上了多個通道模式的話,會多次收到同一個消息。

jredis目前版本沒提供pub/sub支持,不過自己實現一個應該也挺簡單的。整個應用程序可以共享同一個連接。因為redis返回的消息報文中除了消息內容本身外還包括消息相關的通道信息,當收到消息後可以根據不同的通道信息去調用不同的callback來處理。

另外個人覺得redis的pub/sub還是有點太單薄(實現才用150行代碼)。在安全,認證,可靠性這方便都沒有太多支持。
Copyright © Linux教程網 All Rights Reserved