一 前言
雖然有消息隊列,我們還是要了解一下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 的消息是不會持久化
求關注

