redis订阅发布示例

下面的代码使用redis实现订阅/发布。

在redis中可以同时订阅多个频道,如果有消息发布是redis会发出通知。jedis中提供了JedisPubSub抽象类来提供发布/订阅的机制,在实际应用中需要实现JedisPubSub类。

package com.qinying.demo.redis;
import redis.clients.jedis.JedisPubSub;

public class Subscriber extends JedisPubSub {
    @Override
    public void onMessage(String channel, String message) {
        super.onMessage(channel, message);
        System.out.println(channel + ":" + message);
    }
}

上面的类是从JedisPubSub继承的类,我要用它来订阅一些频道,并获得消息。

main方法如下

package com.qinying.demo.redis;

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 = "commonChannel";
    public static Logger logger = Logger.getLogger(Program.class);

    public static void main(String[] args) {
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        JedisPool jedisPool = new JedisPool(poolConfig, "10.2.2.206", 6379, 0);
        final Jedis subscriberJedis = jedisPool.getResource();
        final Subscriber subscriber = new Subscriber();
        final Jedis subscriberJedis2 = jedisPool.getResource();
        final Subscriber subscriber2 = new Subscriber();
        new Thread(new Runnable() {
            public void run() {
                try {
                    logger.info("Subscribing to \"commonChannel\". This thread will be blocked.");
                    subscriberJedis.subscribe(subscriber, CHANNEL_NAME);
                    logger.info("Subscription ended.");
                } catch (Exception e) {
                    logger.error("Subscribing failed.", e);
                }
            }
        }).start();

        new Thread(new Runnable() {
            public void run() {
                try {
                    logger.info("Subscribing to \"commonChannel\". This thread will be blocked.");
                    subscriberJedis2.subscribe(subscriber2, CHANNEL_NAME);
                    logger.info("Subscription ended.");
                } catch (Exception e) {
                    logger.error("Subscribing failed.", e);
                }
            }
        }).start();
        //subscriber.unsubscribe();
        //jedisPool.returnResource(subscriberJedis);
    }
}

在上面的例子中,我们使用JedisPool来获得Jedis的实例。 Jedis类是非线程安全的,但是JedisPool是线程安全的。我使用了两个Jedis实例,一个用来发布消息,另一个订阅频道。

我在另外一个线程中实现订阅。

下面的类实现发布消息到redis的频道中。

package com.qinying.demo.redis;

import org.apache.log4j.Logger;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

public class Publisher {
    private static final Logger logger = Logger.getLogger(Publisher.class);

    public static void main(String[] args) {
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        JedisPool jedisPool = new JedisPool(poolConfig, "10.2.2.206", 6379, 0);
        final Jedis publisherJedis = jedisPool.getResource();

        publisherJedis.publish("commonChannel", "hello");
    }
}

上面的类获得用户的控制台输入,然后发布到redis channel,当用户键入quit时则退出循环

关键点如下:
  • 要在单独的线程中订阅, 因为subscribe会阻塞当前线程的执行。 你可以使用一个PubSub实例来订阅多个Channel
  • 注意Jedis实例是非线程安全的
  • 当需要创建多个jedis实例时要使用JedisPool类,当使用完jedis对象时要放回JedisPool。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,991评论 19 139
  • 1.1 资料 ,最好的入门小册子,可以先于一切文档之前看,免费。 作者Antirez的博客,Antirez维护的R...
    JefferyLcm阅读 17,120评论 1 51
  • 安全性 设置客户端连接后进行任何其他指令前需要使用的密码。 警告:因为redis 速度相当快,所以在一台比较好的服...
    OzanShareing阅读 1,832评论 1 7
  • 一、redis的优势 1、redis简介 redis是速度非常快的非关系型数据库,是内存数据库,可以以key-va...
    我就是要皮阅读 545评论 3 6
  • 我们经常会碰到如下问题: 刷起了朋友圈,一刷半小时就过去了; 本来只是想休息几分钟,随手就点开了一个电视剧,就这样...
    另一种绅士阅读 673评论 0 0