redis發布訂閱模式


一 前言

雖然有消息隊列,我們還是要了解一下redis發布訂閱模式喲!!!!!

二發布訂閱模式

  • PUBLISH 命令向通道發送信息,此客戶端稱為publisher 發布者;
  • SUBSCRIBE 向命令通道訂閱信息,此客戶端稱為subscriber 訂閱者;
  • redis 中 發布訂閱模塊的名字叫着 PubSub,也就是 PublisherSubscriber;
  • 一個發布者向一個通道發送消息,訂閱者可以向多個通道訂閱消息;當發布者向通道發布消息后,如果有訂閱者訂閱該通道,訂閱者就會收到消息;這有點像電台,我收聽了一個電台的頻道,當頻道發送消息后,我就能收到消息;

三PUBSub模塊命令

  • subscribe: 訂閱一個或者多個頻道;
  • unsubscribe: 退訂一個或者多個頻道;
  • publish: 向通道發送消息;
  • psubscribe: 訂閱給定模式相匹配的所有頻道;
  • punsubscribe: 退訂 給定模式所有的頻道,若未指定模式,退訂所有頻道;

具體的命令使用方式 可以使用 help 命令 ;示例如下:

help subscribe

四客戶端實現

通過指令SUBSCRIBE訂閱一個頻道,如果頻道不存在時則新建一個頻道;此時此客戶端就是訂閱者

127.0.0.1:6379> subscribe zszxz
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "zszxz"
3) (integer) 1

通過指令publish向通道發送一個消息;此時客戶端就是發布者

127.0.0.1:6379> publish zszxz "l miss you"
(integer) 1
127.0.0.1:6379>

我們再看看 客戶端就收到消息了

127.0.0.1:6379> subscribe zszxz
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "zszxz"
3) (integer) 1
1) "message"
2) "zszxz"
3) "l miss you"

五java 實現

定義2個訂閱者用於訂閱頻道的消息,在使用jedis 時 需要 繼承 JedisPubSub 類, 並重寫 onMessage 方法; 訂閱者可以在該方法里面進行消息的業務邏輯處理;

訂閱者 1

/**
 * @Author lsc
 * <p>訂閱者1號 </p>
 */
@Component
public class Sub1 extends JedisPubSub {

    @Override
    public void onMessage(String channel, String message) {
        System.out.println("sub1 channel is :"+ channel+ "  mesage is :"+message);
    }
}

訂閱者2

/**
 * @Author lsc
 * <p>訂閱者2號 </p>
 */
@Component
public class Sub2 extends JedisPubSub {

    @Override
    public void onMessage(String channel, String message) {
        System.out.println("sub2 channel is :"+ channel+ "  mesage is :"+message);
    }
}

發布者

/**
 * @Author lsc
 * <p> </p>
 */
@Component
public class Pub {

    public void publishMessage(Jedis jedis, String channel, String msg) {
        jedis.publish(channel,msg);
    }
}

測試類、

注意redis 的 發布訂閱模式 是阻塞模式 ,一個訂閱者需要 重新起一個線程;

    @Autowired
    Pub pub;

    @Autowired
    JedisUtil jedisUtil;

    @Autowired
    Sub1 sub1;

    @Autowired
    Sub1 sub2;

    @Test
    public void test(){

        new Thread(()-> {
            while (true){
                jedisUtil.getJedis().subscribe(sub1,"zszxz");
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //jedisUtil.getJedis().subscribe(sub2,"zszxz");
        }).start();
        pub.publishMessage(jedisUtil.getJedis(),"zszxz","l miss you");
    }

六 缺點

  • PubSub 的生產者來一個消息會直接傳遞給消費者。如果沒有消費者,消息會直接丟棄。如果有多個消費者,一個消費者突然掛掉,生產者會繼續發送消息,另外的消費者可以持續收到消息。但是掛掉的消費者重新連上后,斷連期間的消息會徹底丟失;
  • 如果 Redis 停機重啟,PubSub 的消息是不會持久化

求關注


免責聲明!

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



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