【Redis】Redis的pub\sub在JAVA中的實踐


一、什么是pub/sub?
    publish/subscribe ,即發布訂閱功能。基於實踐系統中,是常用的通信模型,采用事件做為基本的通信機制,提供大規模系統要求的松散耦合的交互方式。訂閱者,以事件定義的方式表達出它有興趣接受的一個時間或一類事件。發布者,發布事件並通知相關訂閱者。
    同時,pub/sub也是一個消息通信模式,主要目的是解除消息發布者和訂閱者之間的耦合,Redis作為pub/sub的一個server,在發布者和訂閱者之間起到了消息路由的作用。
 
二、Redis實現原理簡單總結
    pub/sub功能提供兩種信息機制,分別是“訂閱/發布到頻道”和“訂閱/發布到模式”。
 
    1、頻道的訂閱與信息發送
        語法介紹: 【訂閱頻道】subscribe channel1 channel2 ···    【頻道發布信息】publish channel1 message  【退訂頻道】unsubscribe channel1 ···
        訂閱頻道的存儲:在redis服務中都維持着一個表示服務器狀態的 redis.h/redisServer結構,結構中pubsub_channels屬性是一個字典,用於保存訂閱信息。
              保存結構:該字典是一個鍵值對,鍵為正在被訂閱的頻道,值則是一個鏈表,鏈表中保存所有訂閱這個頻道的客戶端。     
              struct redisServer {
                    //...                    
                    dict *pubsub_channels;
                    //...
               }
              當再次發生訂閱操作,先遍歷pubsub_channels的鍵,如果有就在對應值的鏈表結尾添加客戶端信息。
              因此程序可以通過pubsub_channels來確定某個頻道是否正被訂閱,也可以通過頻道拿到所有訂閱該頻道的客戶端信息。
        頻道發布信息:在某頻道發布信息,遍歷pubsub_channels找到訂閱該頻道的所有客戶端,發送信息。   
           
    2、模式的訂閱與信息發送
        語法介紹:【訂閱模式】psubscribe channel* ···  【punsubscribe channel* ···】
        訂閱模式的存儲: redisServer.pubsub_patterns屬性是一個鏈表,鏈表中每個節點都包含一個redis.h/pubsubPattern結構。
            pubsubPattern中client保存訂閱模式的客戶端,pattern則保存被訂閱的模式。
            struct redisServer {                                                  typedef struct pubsubPattern {
                //...                                                                               redisClient *client;
                list *pubsub_patterns;                                                   robj *pattern;
                //...                                                                        } pubsubPattern;
            };
         發布信息:除了遍歷頻道外,還需匹配模式,然后發送信息。
 
三、項目中應用
 
    參照項目:com.liuxs.runToExpert.redis.pubSub.plus
    注意點:
        1、發布和訂閱主要依賴於 redis.clients.jedis.JedisPubSub 監聽器,所有操作都會在其實現類中對應方法做監聽處理。
        2、如果用同一個jedis對象(即使沒有做單例,從jedisPool中拿的)來發布、訂閱,都會拋出一個異常。
            異常信息:JedisDataException: ERR only (P)SUBSCRIBE / (P)UNSUBSCRIBE / QUIT allowed in...
        3、取消訂閱功能,只有在監聽過程中調用器父類的unsubsribe(channel)實現,如果直接調用拋出會找不到Client異常。
 


免責聲明!

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



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