一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|JavaScript|易語言|

服務器之家 - 編程語言 - JAVA教程 - 淺談java實現redis的發布訂閱(簡單易懂)

淺談java實現redis的發布訂閱(簡單易懂)

2021-04-09 11:10半城楓葉半城雨丶 JAVA教程

本篇文章主要介紹了淺談java實現 redis的發布訂閱(簡單易懂),小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

redis的應用場景實在太多了,現在介紹一下它的幾大特性之一   發布訂閱(pub/sub)。

特性介紹:

什么是redis的發布訂閱(pub/sub)?   Pub/Sub功能(means Publish, Subscribe)即發布及訂閱功能。基于事件的系統中,Pub/Sub是目前廣泛使用的通信模型,它采用事件作為基本的通信機制,提供大規模系統所要求的松散耦合的交互模式:訂閱者(如客戶端)以事件訂閱的方式表達出它有興趣接收的一個事件或一類事件;發布者(如服務器)可將訂閱者感興趣的事件隨時通知相關訂閱者。熟悉設計模式的朋友應該了解這與23種設計模式中的觀察者模式極為相似。

同樣,Redis的pub/sub是一種消息通信模式,主要的目的是解除消息發布者和消息訂閱者之間的耦合,  Redis作為一個pub/sub的server, 在訂閱者和發布者之間起到了消息路由的功能。

如果沒聽懂上述的專業解釋,沒關系,其實我也沒太聽懂。

簡單來講,這里面還有個channel的概念,這里就是頻道的意思,比如你訂閱了銀行的頻道,當你的資金發生變動時,你就會接受到銀行就會通過它的頻道給你發送信息,在這里,你是屬于被動接收的,而不是向銀行索要信息,這個例子中,你就是sub(訂閱者),而銀行就是pub(發布者)。

項目運用場景:

一直都認為你會一樣技術之前,都必須先明白這樣一種技術在哪些地方會被用到,不能盲目的學東西。

看到發布訂閱的特性,用來做一個簡單的實時聊天系統再適合不過了。這是其中之一,當然這樣的東西,我們開發中很少涉及到。再舉一個常用的,在我們的分布式架構中,常常會遇到讀寫分離的場景,在寫入的過程中,就可以使用redis發布訂閱,使得寫入值及時發布到各個讀的程序中,就保證數據的完整一致性。再比如,在一個博客網站中,有100個粉絲訂閱了你,當你發布新文章,就可以推送消息給粉絲們拉。總之場景很多,需要去挖掘。。

回顧java如何操作redis:

redis是一種緩存數據庫,它也是C/S的結構,也就是客戶端和服務端,一般來說,在java中,我們通常使用 jedis(客戶端)去操作redis(服務端),這其中操作的時候,兩者之間肯定要建立連接,就像數據庫鏈接一樣,在關系型數據庫中,我們一般都維護一個連接池,以達到鏈接的復用,來省去建立連接和關閉連接的時間。所以在jedis中,同樣也存在一個jedispool(jedis連接池)的概念,我們都是從池中去取連接使用。

上代碼:

想使用jedis先引入依賴

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

建立一個Publisher (發布者)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class Publisher extends Thread{
 
  private final JedisPool jedisPool;
 
  public Publisher(JedisPool jedisPool) {
    this.jedisPool = jedisPool;
  }
  
  @Override
  public void run() {
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    Jedis jedis = jedisPool.getResource();  //連接池中取出一個連接
    while (true) {
      String line = null;
      try {
        line = reader.readLine();
        if (!"quit".equals(line)) {
          jedis.publish("mychannel", line);  //從 mychannel 的頻道上推送消息
        } else {
          break;
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }
}

再建立一個訂閱者

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Subscriber extends JedisPubSub {
  public Subscriber(){}
  @Override
  public void onMessage(String channel, String message) {    //收到消息會調用
    System.out.println(String.format("receive redis published message, channel %s, message %s", channel, message));
  }
  @Override
  public void onSubscribe(String channel, int subscribedChannels) {  //訂閱了頻道會調用
    System.out.println(String.format("subscribe redis channel success, channel %s, subscribedChannels %d",
        channel, subscribedChannels));
  }
  @Override
  public void onUnsubscribe(String channel, int subscribedChannels) {  //取消訂閱 會調用
    System.out.println(String.format("unsubscribe redis channel, channel %s, subscribedChannels %d",
        channel, subscribedChannels));
 
  }
}

這里訂閱者需要繼承JedisPubSub,來重寫它的三個方法。用途 注釋上已經寫了,很簡單。

我們這里只是定義了一個訂閱者,下面去訂閱頻道。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class SubThread extends Thread {
  private final JedisPool jedisPool;
  private final Subscriber subscriber = new Subscriber();
 
  private final String channel = "mychannel";
 
  public SubThread(JedisPool jedisPool) {
    super("SubThread");
    this.jedisPool = jedisPool;
  }
 
  @Override
  public void run() {
    System.out.println(String.format("subscribe redis, channel %s, thread will be blocked", channel));
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();  //取出一個連接
      jedis.subscribe(subscriber, channel);  //通過subscribe 的api去訂閱,入參是訂閱者和頻道名
    } catch (Exception e) {
      System.out.println(String.format("subsrcibe channel error, %s", e));
    } finally {
      if (jedis != null) {
        jedis.close();
      }
    }
  }
}

最后,再寫一個測試類去跑一下。鍵盤輸入消息,訂閱者就會觸發onMessage方法

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class PubSubDemo {
  public static void main( String[] args )
  {
    // 連接redis服務端
    JedisPool jedisPool = new JedisPool(new JedisPoolConfig(), "127.0.0.1", 6379);
    
    System.out.println(String.format("redis pool is starting, redis ip %s, redis port %d", "127.0.0.1", 6379));
 
    SubThread subThread = new SubThread(jedisPool); //訂閱者
    subThread.start();
 
    Publisher publisher = new Publisher(jedisPool);  //發布者
    publisher.start();
  }
}

看打印結果

淺談java實現redis的發布訂閱(簡單易懂)

附上代碼地址  https://github.com/fangyong1421/redis

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:http://www.cnblogs.com/xinde123/p/8489054.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 色婷婷久久综合中文久久一本` | 日韩一区二区三区精品 | 日韩免费在线视频 | 91色porny| 99青青青精品视频在线 | 美女被免费视频 | 肉文np高h | 欧美黑人性猛交╳xx╳动态图 | 精品性影院一区二区三区内射 | 性俄罗斯xxxxxhd| 欧美性4khd720 | 女人张开腿让男人桶爽 | 午夜精品久久久久久久2023 | 国产欧美日韩高清专区ho | 草逼吧 | 日韩精品亚洲专区在线影视 | bbwfreehd女厕所ved| 香蕉久久一区二区三区啪啪 | 欧美精品色精品一区二区三区 | 成人午夜影院在线观看 | 午夜AV国产欧美亚洲高清在线 | 欧美男同videos| 青草免费在线观看 | 亚洲精品网址 | 国产精品视频免费一区二区三区 | 午夜视频在线网站 | 成年美女黄网色大观看全 | 新版孕妇bbwbbwbbw | 九九久久国产 | 四虎在线视频免费观看 | 精品视频一区二区观看 | avtt天堂网手机版亚洲 | 奇米影视欧美 | 日韩在线视精品在亚洲 | 日本片免费观看一区二区 | 九九热在线观看视频 | 男人j放进女人的p视频免费 | 青青青手机视频在线观看 | 五月天在线视频观看 | 俄罗斯男男激情1069gay | 久草草在线视视频 |