成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

面試被問到Redis實現發布與訂閱,手摸手教

開發 后端 其他數據庫 Redis
Redis發布與發布功能(Pub/Sub)是基于事件座位基本的通信機制,是目前應用比較普遍的通信模型,它的目的主要是解除消息的發布者與訂閱者之間的耦合關系。

簡介

Redis發布與發布功能(Pub/Sub)是基于事件座位基本的通信機制,是目前應用比較普遍的通信模型,它的目的主要是解除消息的發布者與訂閱者之間的耦合關系。

Redis作為消息發布和訂閱之間的服務器,起到橋梁的作用,在Redis里面有一個channel的概念,也就是頻道,發布者通過指定發布到某個頻道,然后只要有訂閱者訂閱了該頻道,該消息就會發送給訂閱者,原理圖如下所示:

Redis同時也可以使用list類型實現消息隊列(消息隊列的實現以及應用場景會在下一篇文章繼續講解)。

Redis的發布與訂閱的功能應用還是比較廣泛的,它的應用場景有很多。比如:最常見的就是實現實時聊天的功能,還是有就是博客的粉絲文章的推送,當博主推送原創文章的時候,就會將文章實時推送給博主的粉絲。

簡介完Redis的發布于訂閱功能,下面就要來實操一下,包括linux命令的實操和java代碼的實現。

命令實操

這里就假設各位讀者都已經安裝好自己的虛擬機環境和Redis了,若是沒有安裝好的,可以參考這一篇博文:https://www.cnblogs.com/zuidongfeng/p/8032505.html

我這里是已經安裝好了Redis了,直接啟動我們的Redis,我已經設置好了開機啟動,上面的那篇博文有講解怎么設置開機啟動。

發布消息

Redis中發布消息的命令是publish,具體使用如下所示:

PUBLISH test "haha":test表示頻道的名稱,haha表示發布的內容,這樣就完成了一個一個消息的發布,后面的返回(integer)0表示0人訂閱。

訂閱頻道

于此同時再啟動一個窗口,這個窗口作為訂閱者,訂閱者的命令subscribe,使用SUBSCRIBE test就表示訂閱了test這個頻道

訂閱后返回的結果中由三條信息,第一個表示類型、第二個表示訂閱的頻道,第三個表示訂閱的數量。接著在第一個窗口進行發布消息:

可以看到發布者發布的消息,訂閱者都會實時的接收到,并發訂閱者收到的信息中也會出現三條信息,分別表示:返回值的類型、頻道名稱、消息內容。

取消訂閱

若是想取消之前的訂閱可以使用unsubscribe命令,格式為: 

  1. unsubscribe  頻道名稱  
  2. // 取消之前訂閱的test頻道  
  3. unsubscribe  test 

輸入命令后,返回以下結果: 

  1. [root@pinyoyougou-docker src]# ./redis-cli   
  2. 127.0.0.1:6379> UNSUBSCRIBE test  
  3. 1) "unsubscribe" 
  4. 2) "test"  
  5. 3) (integer) 0 

它分別表示:返回值的類型、頻道的名稱、該頻道訂閱的數量。

按模式訂閱

除了直接以特定的名城進行訂閱,還可以按照模式進行訂閱,模式的方式進行訂閱可以一次訂閱多個頻道,按照模式進行訂閱的命令為psubscribe,具體格式如下: 

  1. psubscribe  模式  
  2. // 表示訂閱名稱以ldc開頭的頻道  
  3. psubscribe  ldc* 

輸入上面的命令后,返回如下結果: 

  1. 127.0.0.1:6379> PSUBSCRIBE ldc*  
  2. Reading messages... (press Ctrl-C to quit)  
  3. 1) "psubscribe"  
  4. 2) "ldc*"  
  5. 3) (integer) 1 

這個也是非常簡單,分別表示:返回的類型(表示按模式訂閱類型)、訂閱的模式、訂閱數。

取消按模式訂閱

假如你想取消之前的按模式訂閱,可以使用punsubscribe來取消,具體格式: 

  1. punsubscribe 模式  
  2. // 取消頻道名稱按照ldc開頭的頻道  
  3. punsubscribe ldc* 

他的返回值,如下所示: 

  1. 127.0.0.1:6379> PUNSUBSCRIBE ldc*  
  2. 1) "punsubscribe"  
  3. 2) "ldc*"  
  4. 3) (integer) 0 

這個就不多說了,表示的意思和上面的一樣,可以看到上面的命令都是有規律的訂閱SUBSCRIBE,取消就是UNSUBSCRIBE,前面加前綴UN,按模式訂閱也是。

查看訂閱消息

(1)你想查看某一個模式下訂閱數是大于零的頻道,可以使用如下格式的命令進行操作: 

  1. pubsub channels 模式  
  2. // 查看頻道名稱以ldc模式開頭的訂閱數大于零的頻道  
  3. pubsub channels ldc* 

(2)假如你想查看某一個頻道的訂閱數,可以使用如下命令: 

  1. pubsub numsub 頻道名稱 

(3)查看按照模式的訂閱數,可以使用如下命令進行操作: 

  1. pubsub numpat 

到這里以上的命令操作就基本結束了,下面就來代碼實戰。

代碼實練

(1)首先第一步想要操作Redis,再SpringBoot項目中引入jedis的依賴,畢竟jedis是官方推薦使用操作Redis的工具。 

  1. <dependency>  
  2.     <groupId>redis.clients</groupId>  
  3.     <artifactId>jedis</artifactId>  
  4.     <version>2.9.0</version>  
  5. </dependency> 

(2)然后創建發布者Publisher,用于消息的發布,具體代碼如下: 

  1. package com.ldc.org.myproject.demo.redis;  
  2. import java.io.BufferedReader;  
  3. import java.io.IOException;  
  4. import java.io.InputStreamReader;  
  5. import redis.clients.jedis.Jedis;  
  6. import redis.clients.jedis.JedisPool;  
  7. /**  
  8.  * 發布者  
  9.  * @author liduchang  
  10.  *  
  11.  */ 
  12.  public class Publisher extends Thread{  
  13.  // 連接池   
  14.  private final JedisPool jedisPool;  
  15.  // 發布頻道名稱  
  16.  private String name;  
  17.  public Publisher(JedisPool jedisPool, String name) {  
  18.   super();  
  19.   this.jedisPool = jedisPool;  
  20.   this.name = name;  
  21.  }  
  22.  @Override  
  23.  public void run() {  
  24.   // 獲取要發布的消息  
  25.   BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));  
  26.   // 獲取連接  
  27.   Jedis resource = jedisPool.getResource();  
  28.   while (true) {  
  29.    String message = null 
  30.    try {  
  31.     message = reader.readLine();  
  32.     if (!"exit".equals(message)) {  
  33.      // 發布消息  
  34.      resource.publish(name, "發布者:"+Thread.currentThread().getName()+"發布消息:"+message);  
  35.     } else {  
  36.      break;  
  37.     }  
  38.    } catch (IOException e) {  
  39.     e.printStackTrace();  
  40.    }  
  41.   } 
  42.  }  

(3)接著創建訂閱類Subscriber,并且繼承JedisPubSub 類,重寫onMessage、onSubscribe、onUnsubscribe三個方法,這三個方法的調用時機在注釋上都有說明,具體的實現代碼如下: 

  1. package com.ldc.org.myproject.demo.redis;  
  2. import com.fasterxml.jackson.core.sym.Name;  
  3. import redis.clients.jedis.JedisPubSub;  
  4. /**  
  5.  * 訂閱者  
  6.  * @author liduchang  
  7.  */  
  8. public class Subscriber extends JedisPubSub {  
  9.  //訂閱頻道名稱  
  10.  private String name;  
  11.  public Subscriber(String name) {  
  12.   this.name = name;  
  13.  }  
  14.  /**  
  15.   * 訂閱者收到消息時會調用  
  16.   */  
  17.  @Override  
  18.  public void onMessage(String channel, String message) {  
  19.   // TODO Auto-generated method stub  
  20.   super.onMessage(channel, message);  
  21.   System.out.println("頻道:"+channel+"  接受的消息為:"+message);  
  22.  }  
  23.  /**  
  24.   * 訂閱了頻道會被調用  
  25.   */  
  26.  @Override  
  27.  public void onSubscribe(String channel, int subscribedChannels) {  
  28.   System.out.println("訂閱了頻道:"+channel+"  訂閱數為:"+subscribedChannels);  
  29.  }  
  30.  /**  
  31.   * 取消訂閱頻道會被調用  
  32.   */  
  33.  @Override 
  34.  public void onUnsubscribe(String channel, int subscribedChannels) {  
  35.   System.out.println("取消訂閱的頻道:"+channel+"  訂閱的頻道數量為:"+subscribedChannels);  
  36.  }  

(4)這次創建的才是真正的訂閱者SubThread,上面的Subscriber是指為了測試實訂閱的時候或者發布消息,能夠有信息輸出: 

  1. package com.ldc.org.myproject.demo.redis; 
  2. import redis.clients.jedis.Jedis;  
  3. import redis.clients.jedis.JedisPool;  
  4. /**  
  5.  * 訂閱者線程  
  6.  * @author liduchang  
  7.  *  
  8.  */  
  9. public class SubThread extends Thread {  
  10.  private final JedisPool jedisPool;  
  11.  private final Subscriber subscriber;  
  12.  private String name;  
  13.  public SubThread(JedisPool jedisPool,Subscriber subscriber,String name) { 
  14.   super();  
  15.   this.jedisPool = jedisPool;  
  16.   this.subscriber = subscriber;  
  17.   this.name = name;  
  18.  }  
  19.  @Override  
  20.  public void run() {  
  21.   Jedis jedis = null 
  22.   try {  
  23.    jedis = jedisPool.getResource();  
  24.    // 訂閱頻道為name  
  25.    jedis.subscribe(subscriber, name);  
  26.   } catch (Exception e) {  
  27.    System.err.println("訂閱失敗");  
  28.       e.printStackTrace();  
  29.   } finally {  
  30.    if (jedis!=null) {  
  31.      // jedis.close();  
  32.      //歸還連接到redis池中  
  33.     jedisPool.returnResource(jedis);  
  34.    }  
  35.   }  
  36.  }  

(5)后面就是測試了,分別測試發布與訂閱的測試,發布者為TestPublisher,訂閱者為TestSubscriber: 

  1. package com.ldc.org.myproject.demo.redis;  
  2. import java.util.concurrent.ExecutorService;  
  3. import java.util.concurrent.Executors;  
  4. import java.util.concurrent.TimeUnit;  
  5. import redis.clients.jedis.JedisPool;  
  6. public class TestPublisher {  
  7.  public static void main(String[] args) throws InterruptedException {  
  8.   JedisPool jedisPool = new JedisPool("192.168.163.155");  
  9.   // 向ldc頻道發布消息  
  10.   Publisher publisher = new Publisher(jedisPool, "ldc");  
  11.   publisher.start();  
  12.  }  

訂閱者 

  1. package com.ldc.org.myproject.demo.redis;  
  2. import java.util.concurrent.ExecutorService;  
  3. import java.util.concurrent.Executors;  
  4. import java.util.concurrent.TimeUnit;  
  5. import redis.clients.jedis.JedisPool;  
  6. public class TestSubscriber1 {  
  7.  public static void main(String[] args) throws InterruptedException {  
  8.   JedisPool jedisPool = new JedisPool("192.168.163.155",6379);  
  9.   Subscriber subscriber = new Subscriber("黎杜");  
  10.   // 訂閱ldc頻道  
  11.   SubThread threadnew SubThread(jedisPool, subscriber, "ldc");  
  12.   thread.start();  
  13.   Thread.sleep(600000);  
  14.   // 取消訂閱  
  15.   subscriber.unsubscribe("ldc");  
  16.  } 

這里為了測試方便就直接創建線程的方式,更好的話可以使用線程池的方式通過線程池的submit方法來執行線程,若是不用了可以使用shutdown方式關閉。 

 

責任編輯:龐桂玉 來源: 數據庫開發
相關推薦

2025-02-25 09:29:34

2022-08-15 09:22:12

JWT認證系統

2022-09-06 08:40:33

應用系統登錄方式Spring

2022-01-26 00:02:00

Nacos服務注冊中心

2017-12-18 17:21:56

AndroidJava內存泄漏

2024-03-06 08:00:56

javaAQS原生

2024-01-10 08:16:08

Redis集成JMS

2020-09-23 07:45:32

Docker前端

2023-04-10 09:32:00

DubboJava

2024-07-02 11:42:53

SpringRedis自定義

2021-07-19 07:01:20

Chrome 插件瀏覽器

2022-12-02 07:28:58

Event訂閱模式Spring

2025-01-23 08:53:15

2021-11-12 07:00:46

tsdx開發環境

2023-12-14 10:10:09

pythonRedis開發

2019-02-21 10:49:51

Redis持久化恢復

2020-04-30 10:24:35

Spring循環依賴Java

2019-11-29 10:16:36

高并發系統緩存

2023-11-01 16:50:58

2022-08-15 09:02:22

Redis模式訂閱消息
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 黄色网址av| 久久久久久亚洲国产精品 | 91n成人 | 国产精品伦一区二区三级视频 | 久久久久久九九九九九九 | 91精品国产综合久久久久 | 97精品视频在线观看 | 国产精品三级久久久久久电影 | 国产精品日韩欧美一区二区三区 | 网黄在线| av黄色在线 | 亚洲视频免费 | 亚洲视频在线播放 | 国产精品无码专区在线观看 | 精品啪啪 | 精品日韩一区 | 91中文| 精品不卡| 韩日精品视频 | 九九在线精品视频 | 久草新在线 | 精品免费视频 | 国产福利一区二区 | 亚洲综合区 | 99欧美精品| 天天干天天爱天天操 | 欧美日韩成人在线观看 | 91视频网 | 久久国产精品一区 | 欧美日韩在线免费观看 | 美国黄色一级片 | 中文字幕在线观看一区 | 无吗视频 | 天天综合日日夜夜 | 日韩高清在线观看 | 美日韩精品 | 91麻豆精品国产91久久久久久 | 综合一区 | 91av在线免费观看 | 日韩精品一区在线 | 欧美特级黄色 |