六 redis學習筆記之發布訂閱

來源:互聯網
上載者:User
        發布訂閱(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或者http://terrylee.me/blog/post/2011/01/26/redis-internal-part3.aspx。這個報文內容有兩部分,第一部分表示該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行代碼)。在安全,認證,可靠性這方便都沒有太多支援。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.