天天看點

redis 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先引入依賴

redis.clients

jedis

2.9.0

建立一個Publisher (釋出者)

public class Publisher extendsThread{private finalJedisPool jedisPool;publicPublisher(JedisPool jedisPool) {this.jedisPool =jedisPool;

}

@Overridepublic voidrun() {

BufferedReader reader= new BufferedReader(newInputStreamReader(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();

}

}

}

}

再建立一個訂閱者

public class Subscriber extendsJedisPubSub {publicSubscriber(){}

@Overridepublic void onMessage(String channel, String message) { //收到消息會調用

System.out.println(String.format("receive redis published message, channel %s, message %s", channel, message));

}

@Overridepublic void onSubscribe(String channel, int subscribedChannels) { //訂閱了頻道會調用

System.out.println(String.format("subscribe redis channel success, channel %s, subscribedChannels %d",

channel, subscribedChannels));

}

@Overridepublic void onUnsubscribe(String channel, int subscribedChannels) { //取消訂閱 會調用

System.out.println(String.format("unsubscribe redis channel, channel %s, subscribedChannels %d",

channel, subscribedChannels));

}

}

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

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

public class SubThread extendsThread {private finalJedisPool jedisPool;private final Subscriber subscriber = newSubscriber();private final String channel = "mychannel";publicSubThread(JedisPool jedisPool) {super("SubThread");this.jedisPool =jedisPool;

}

@Overridepublic voidrun() {

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方法

public classPubSubDemo {public static voidmain( 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();

}

}

看列印結果

redis java 釋出訂閱_java實作 redis的釋出訂閱(簡單易懂)