【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异常。
 

猜你喜欢

转载自www.cnblogs.com/liuxs13/p/9272393.html
今日推荐