偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

面試被問(wèn)到Redis實(shí)現(xiàn)發(fā)布與訂閱,手摸手教

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

簡(jiǎn)介

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

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

Redis同時(shí)也可以使用list類型實(shí)現(xiàn)消息隊(duì)列(消息隊(duì)列的實(shí)現(xiàn)以及應(yīng)用場(chǎng)景會(huì)在下一篇文章繼續(xù)講解)。

Redis的發(fā)布與訂閱的功能應(yīng)用還是比較廣泛的,它的應(yīng)用場(chǎng)景有很多。比如:最常見(jiàn)的就是實(shí)現(xiàn)實(shí)時(shí)聊天的功能,還是有就是博客的粉絲文章的推送,當(dāng)博主推送原創(chuàng)文章的時(shí)候,就會(huì)將文章實(shí)時(shí)推送給博主的粉絲。

簡(jiǎn)介完Redis的發(fā)布于訂閱功能,下面就要來(lái)實(shí)操一下,包括linux命令的實(shí)操和java代碼的實(shí)現(xiàn)。

命令實(shí)操

這里就假設(shè)各位讀者都已經(jīng)安裝好自己的虛擬機(jī)環(huán)境和Redis了,若是沒(méi)有安裝好的,可以參考這一篇博文:https://www.cnblogs.com/zuidongfeng/p/8032505.html

我這里是已經(jīng)安裝好了Redis了,直接啟動(dòng)我們的Redis,我已經(jīng)設(shè)置好了開(kāi)機(jī)啟動(dòng),上面的那篇博文有講解怎么設(shè)置開(kāi)機(jī)啟動(dòng)。

發(fā)布消息

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

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

訂閱頻道

于此同時(shí)再啟動(dòng)一個(gè)窗口,這個(gè)窗口作為訂閱者,訂閱者的命令subscribe,使用SUBSCRIBE test就表示訂閱了test這個(gè)頻道

訂閱后返回的結(jié)果中由三條信息,第一個(gè)表示類型、第二個(gè)表示訂閱的頻道,第三個(gè)表示訂閱的數(shù)量。接著在第一個(gè)窗口進(jìn)行發(fā)布消息:

可以看到發(fā)布者發(fā)布的消息,訂閱者都會(huì)實(shí)時(shí)的接收到,并發(fā)訂閱者收到的信息中也會(huì)出現(xiàn)三條信息,分別表示:返回值的類型、頻道名稱、消息內(nèi)容。

取消訂閱

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

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

輸入命令后,返回以下結(jié)果: 

  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 

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

按模式訂閱

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

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

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

  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 

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

取消按模式訂閱

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

  1. punsubscribe 模式  
  2. // 取消頻道名稱按照l(shuí)dc開(kāi)頭的頻道  
  3. punsubscribe ldc* 

他的返回值,如下所示: 

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

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

查看訂閱消息

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

  1. pubsub channels 模式  
  2. // 查看頻道名稱以ldc模式開(kāi)頭的訂閱數(shù)大于零的頻道  
  3. pubsub channels ldc* 

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

  1. pubsub numsub 頻道名稱 

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

  1. pubsub numpat 

到這里以上的命令操作就基本結(jié)束了,下面就來(lái)代碼實(shí)戰(zhàn)。

代碼實(shí)練

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

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

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

  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.  * 發(fā)布者  
  9.  * @author liduchang  
  10.  *  
  11.  */ 
  12.  public class Publisher extends Thread{  
  13.  // 連接池   
  14.  private final JedisPool jedisPool;  
  15.  // 發(fā)布頻道名稱  
  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.   // 獲取要發(fā)布的消息  
  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.      // 發(fā)布消息  
  34.      resource.publish(name, "發(fā)布者:"+Thread.currentThread().getName()+"發(fā)布消息:"+message);  
  35.     } else {  
  36.      break;  
  37.     }  
  38.    } catch (IOException e) {  
  39.     e.printStackTrace();  
  40.    }  
  41.   } 
  42.  }  

(3)接著創(chuàng)建訂閱類Subscriber,并且繼承JedisPubSub 類,重寫(xiě)onMessage、onSubscribe、onUnsubscribe三個(gè)方法,這三個(gè)方法的調(diào)用時(shí)機(jī)在注釋上都有說(shuō)明,具體的實(shí)現(xiàn)代碼如下: 

  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.   * 訂閱者收到消息時(shí)會(huì)調(diào)用  
  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.   * 訂閱了頻道會(huì)被調(diào)用  
  25.   */  
  26.  @Override  
  27.  public void onSubscribe(String channel, int subscribedChannels) {  
  28.   System.out.println("訂閱了頻道:"+channel+"  訂閱數(shù)為:"+subscribedChannels);  
  29.  }  
  30.  /**  
  31.   * 取消訂閱頻道會(huì)被調(diào)用  
  32.   */  
  33.  @Override 
  34.  public void onUnsubscribe(String channel, int subscribedChannels) {  
  35.   System.out.println("取消訂閱的頻道:"+channel+"  訂閱的頻道數(shù)量為:"+subscribedChannels);  
  36.  }  

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

  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)后面就是測(cè)試了,分別測(cè)試發(fā)布與訂閱的測(cè)試,發(fā)布者為T(mén)estPublisher,訂閱者為T(mén)estSubscriber: 

  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頻道發(fā)布消息  
  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.  } 

這里為了測(cè)試方便就直接創(chuàng)建線程的方式,更好的話可以使用線程池的方式通過(guò)線程池的submit方法來(lái)執(zhí)行線程,若是不用了可以使用shutdown方式關(guān)閉。 

 

責(zé)任編輯:龐桂玉 來(lái)源: 數(shù)據(jù)庫(kù)開(kāi)發(fā)
相關(guān)推薦

2025-02-25 09:29:34

2022-08-15 09:22:12

JWT認(rèn)證系統(tǒng)

2022-01-26 00:02:00

Nacos服務(wù)注冊(cè)中心

2022-09-06 08:40:33

應(yīng)用系統(tǒng)登錄方式Spring

2024-01-10 08:16:08

Redis集成JMS

2017-12-18 17:21:56

AndroidJava內(nèi)存泄漏

2024-03-06 08:00:56

javaAQS原生

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開(kāi)發(fā)環(huán)境

2023-12-14 10:10:09

pythonRedis開(kāi)發(fā)

2019-02-21 10:49:51

Redis持久化恢復(fù)

2020-04-30 10:24:35

Spring循環(huán)依賴Java

2019-11-29 10:16:36

高并發(fā)系統(tǒng)緩存

2023-11-01 16:50:58

2022-08-15 09:02:22

Redis模式訂閱消息
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)