发布订阅(pub/sub)是一种消息通信模式,主要的目的是解耦消息发布者和消息订阅者之间的耦合,这点和设计模式中的观察者模式比较相似。pub /sub不仅仅解决发布者和订阅者直接代码级别耦合也解决两者在物理部署上的耦合。redis作为一个pub/sub server,在订阅者和发布者之间起到了消息路由的功能。订阅者可以通过subscribe和psubscribe命令向redis server订阅自己感兴趣的消息类型,redis将消息类型称为通道(channel)。当发布者通过publish命令向redis server发送特定类型的消息时。订阅该消息类型的全部client都会收到此消息。这里消息的传递是多对多的。一个client可以订阅多个 channel,也可以向多个channel发送消息。
引入jedis客户端:
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.3.1</version>
</dependency>
代码实现:
1.消息监听器RedisPubSubListener.java
package cn.slimsmart.redis.demo;
import redis.clients.jedis.JedisPubSub;
//发布订阅 消息监听
public class RedisPubSubListener extends JedisPubSub {
// 取得订阅的消息后的处理
@Override
public void onMessage(String channel, String message) {
System.out.println("onMessage: channel[" + channel + "], message[" + message + "]");
}
// 取得按表达式的方式订阅的消息后的处理
@Override
public void onPMessage(String pattern, String channel, String message) {
System.out.println("onPMessage: pattern[" + pattern + "],channel[" + channel + "], message[" + message + "]");
}
// 初始化按表达式的方式订阅时候的处理
@Override
public void onPSubscribe(String channel, int subscribedChannels) {
System.out.println("onSubscribe: channel[" + channel + "]," + "subscribedChannels[" + subscribedChannels + "]");
}
// 取消按表达式的方式订阅时候的处理
@Override
public void onPUnsubscribe(String channel, int subscribedChannels) {
System.out.println("onUnsubscribe: channel[" + channel + "], " + "subscribedChannels[" + subscribedChannels + "]");
}
// 初始化订阅时候的处理
@Override
public void onSubscribe(String pattern, int subscribedChannels) {
System.out.println("onPUnsubscribe: pattern[" + pattern + "]," +
"subscribedChannels[" + subscribedChannels + "]");
}
// 取消订阅时候的处理
@Override
public void onUnsubscribe(String pattern, int subscribedChannels) {
System.out.println("onPSubscribe: pattern[" + pattern + "], " +
"subscribedChannels[" + subscribedChannels + "]");
}
}
2.消息发布Publisher.java
package cn.slimsmart.redis.demo;
import redis.clients.jedis.Jedis;
//发布消息
public class Publisher {
public void publish(final Jedis redisClient) {
new Thread(new Runnable() {
@SuppressWarnings("static-access")
@Override
public void run() {
try {
Thread.currentThread().sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发布:log");
redisClient.publish("log.debug", "log is debug.");
redisClient.publish("log.info", "log is info.");
redisClient.publish("log.error", "log is error.");
}
}).start();
}
}
3.消息订阅
package cn.slimsmart.redis.demo;
import redis.clients.jedis.Jedis;
//订阅消息
public class Subscriber {
public void psub(final Jedis redisClient, final RedisPubSubListener listener) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("订阅:log.debug");
// 订阅得到信息在lister的onMessage(...)方法中进行处理
// 订阅多个频道
// redisClient.subscribe(listener, "log.debug", "log.info");
// redisClient.subscribe(listener, new String[]{"log.debug","log.info"});
redisClient.psubscribe(listener, new String[] { "log.*" });//使用模式匹配的方式设置频道
}
}).start();
}
}
4.启动服务Main.java
package cn.slimsmart.redis.demo;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class Main {
public static void main(String[] args) {
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxIdle(0);
config.setMaxTotal(20);
config.setMaxWaitMillis(1000);
config.setTestOnBorrow(true);
//创建连接池
JedisPool pool = new JedisPool(config, "192.168.100.205", 6379);
//获取客户端
Jedis redisClient1 = pool.getResource();
Jedis redisClient2 = pool.getResource();
RedisPubSubListener listener = new RedisPubSubListener();
Publisher pub = new Publisher();
pub.publish(redisClient2); //发布一个频道
Subscriber sub = new Subscriber();
sub.psub(redisClient1, listener); // 订阅一个频道
}
}
5.运行Main看一下结果
订阅:log.debug
onSubscribe: channel[log.*],subscribedChannels[1]
发布:log
onPMessage: pattern[log.*],channel[log.debug], message[log is debug.]
onPMessage: pattern[log.*],channel[log.info], message[log is info.]
onPMessage: pattern[log.*],channel[log.error], message[log is error.]
或者在redis客户端使用redis-cli
输入:publish log.warn "log is warn" 观察接收消息。
与spring结合参考:http://blog.csdn.net/zhu_tianwei/article/details/17752553