redis pub sub java_redis pub/sub 使用redis完成发布订阅

一、需要3.0以上版本的redis

二、redis-cli实现发布订阅

先开启一个redis-cli(S1),并监听着china这个channel

subcribe china

8f477c24c84657c9b7f586768c4b4fce.png

此时A1处于监听状态

然后再开启一个redis-cli(P1),并向china这个channel发布helloWorld消息

publish china helloWorld

3dcefcdab22049b2f202773e16207578.png

这是我们会发现A1监听到了这个helloWorld消息

ace1f8f475d1aa91351b0e3108cb1043.png

同样,我们开启多个监听窗口,这时我们会发现,他们都可以收到这个helloWorld消息,这和MQ中间件中的发布订阅相同,只有在发布的时刻监听的监听者可以消费到这条消息。

三、Jedis实现发布订阅

redis.clients

jedis

2.8.0

log4j

log4j

1.2.17

Jedis中的JedisPubSub抽象类提供了订阅和取消的功能。想处理订阅和取消订阅某些channel的相关事件,我们得扩展JedisPubSub类并实现相关的方法:

import org.apache.log4j.Logger;

import redis.clients.jedis.JedisPubSub;

public class Subscriber extends JedisPubSub {//注意这里继承了抽象类JedisPubSub

private static final Logger LOGGER = Logger.getLogger(Subscriber.class);

@Override

public void onMessage(String channel, String message) {

LOGGER.info(String.format("Message. Channel: %s, Msg: %s", channel, message));

}

@Override

public void onPMessage(String pattern, String channel, String message) {

LOGGER.info(String.format("PMessage. Pattern: %s, Channel: %s, Msg: %s",

pattern, channel, message));

}

@Override

public void onSubscribe(String channel, int subscribedChannels) {

LOGGER.info("onSubscribe");

}

@Override

public void onUnsubscribe(String channel, int subscribedChannels) {

LOGGER.info("onUnsubscribe");

}

@Override

public void onPUnsubscribe(String pattern, int subscribedChannels) {

LOGGER.info("onPUnsubscribe");

}

@Override

public void onPSubscribe(String pattern, int subscribedChannels) {

LOGGER.info("onPSubscribe");

}

}

有了订阅者,我们还需要一个发布者:

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import org.apache.log4j.Logger;

import redis.clients.jedis.Jedis;

public class Publisher {

private static final Logger LOGGER = Logger.getLogger(Publisher.class);

private final Jedis publisherJedis;

private final String channel;

public Publisher(Jedis publisherJedis, String channel) {

this.publisherJedis = publisherJedis;

this.channel = channel;

}

/**

* 不停的读取输入,然后发布到channel上面,遇到quit则停止发布。

*/

public void startPublish() {

LOGGER.info("Type your message (quit for terminate)");

try {

BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

while (true) {

String line = reader.readLine();

if (!"quit".equals(line)) {

publisherJedis.publish(channel, line);

} else {

break;

}

}

} catch (IOException e) {

LOGGER.error("IO failure while reading input", e);

}

}

}

为简单起见,这个发布者接收控制台的输入,然后将输入的消息发布到指定的channel上面,如果输入quit,则停止发布消息。

接下来是主函数:

import org.apache.log4j.Logger;

import redis.clients.jedis.Jedis;

import redis.clients.jedis.JedisPool;

import redis.clients.jedis.JedisPoolConfig;

public class Program {

public static final String CHANNEL_NAME = "MyChannel";

//我这里的Redis是一个集群,192.168.56.101和192.168.56.102都可以使用

public static final String REDIS_HOST = "192.168.56.101";

public static final int REDIS_PORT = 7000;

private final static Logger LOGGER = Logger.getLogger(Program.class);

private final static JedisPoolConfig POOL_CONFIG = new JedisPoolConfig();

private final static JedisPool JEDIS_POOL =

new JedisPool(POOL_CONFIG, REDIS_HOST, REDIS_PORT, 0);

public static void main(String[] args) throws Exception {

final Jedis subscriberJedis = JEDIS_POOL.getResource();

final Jedis publisherJedis = JEDIS_POOL.getResource();

final Subscriber subscriber = new Subscriber();

//订阅线程:接收消息

new Thread(new Runnable() {

public void run() {

try {

LOGGER.info("Subscribing to \"MyChannel\". This thread will be blocked.");

//使用subscriber订阅CHANNEL_NAME上的消息,这一句之后,线程进入订阅模式,阻塞。

subscriberJedis.subscribe(subscriber, CHANNEL_NAME);

//当unsubscribe()方法被调用时,才执行以下代码

LOGGER.info("Subscription ended.");

} catch (Exception e) {

LOGGER.error("Subscribing failed.", e);

}

}

}).start();

//主线程:发布消息到CHANNEL_NAME频道上

new Publisher(publisherJedis, CHANNEL_NAME).startPublish();

publisherJedis.close();

//Unsubscribe

subscriber.unsubscribe();

subscriberJedis.close();

}

}

打印出来的结果:

74bc36884122e5f3fced201cb4a6ee6f.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值