Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。

 

我们需要Redis中的功能就是发布订阅的功能:

    1、我们调用publish方法,进行广播,发送一条消息

    2、当订阅者subscribe订阅这个广播的时候,就会收到这个message,然后去判断这个message告诉我了什么

注意:

      1、当然订阅者和发布者都是可以是多个。

      2、当长时间未发消息,订阅者会断开,所以我们需要定时发送心跳。

 

下边是上述的代码

订阅者


public class MySubscriber {
	private static GedisCommands gedis = GedisUtils.getInstance();

	public static void subscirbe() {
		SubscribeCommands subscribe = gedis.getSubscribeCommands();
		subscribe.getStatefulConnection().addListener(new SubscribeListener());
		subscribe.subscribe("ChannelName");
	}

	private static class SubscribeListener implements RedisPubSubListener<String, String> {

        @Override
        public void message(String channel, String message) {
            if ("heart".equals(message)) { // 心跳的消息
                LocalLog.info("", "收到心跳,channel={},message={}", channel, message);
            } else if ("change".equals(message)) { // mongo变更的消息
                RedisCache.reload();
                LocalLog.info("", "mongodb生变更,channel={},message={}", channel, message);
            } else {
                LocalLog.warn("", "频道={},收到异常message={}", channel, message);
            }
        }

        @Override
        public void message(String pattern, String channel, String message) {
            message(channel, message);
        }

        @Override
        public void subscribed(String channel, long count) {
            LocalLog.info("", "subscribed 频道={},订阅频道数={}", channel, count);
        }

        @Override
        public void psubscribed(String pattern, long count) {
            LocalLog.info("", "psubscribed pattern={},订阅频道数={}", pattern, count);
        }

        @Override
        public void unsubscribed(String channel, long count) {
            LocalLog.info("", "unsubscribed 频道={},订阅频道数={}", channel, count);
        }

        @Override
        public void punsubscribed(String pattern, long count) {
            LocalLog.info("", "punsubscribed pattern={},订阅频道数={}", pattern, count);
        }

    }
}


发布者


public class MyPublisher {
	private static GedisCommands gedis = GedisUtils.getInstance();
	private static PublishCommands publish = gedis.getPublishCommands();

	/**
	 * 信息变更通知发布
	 * @param channel 频道
	 * @param message 发生变动的事件流定义信息JSON串
	 */
	public static void publish(String channel, String message) {
		try {

			// 发布事件配置信息更新通知 
			publish.publish(channel, message);
		} catch (Exception e) {
			LocalLog.error("", "发布订阅=>出错", e);
		}

	}

}


mongo的增删改查的dao中一个方法


@Override
    public void updateUser(User user) {
        try {

            User oldUser = findUserById(user.getId());
            if (oldUser != null) {
                mongoDBDao.save(user);
            }

            // 变更通知,通知订阅者
            String jsonStr = JSON.toJSONString(user);

            MyPublisher.publish("ChannelName", "change");
            LocalLog.info("事件定义=>更改事件定义成功,message =" + jsonStr);
        } catch (Exception e) {
            LocalLog.error("事件定义=>更新事件定义出错,cause=" + ThrowableUtils.cause(e));
        }
    }


维持心跳的定时器


**
 * redis发布订阅维持心跳。一分钟发送一条消息
 */
public class HeartBeatTask {
    private static GedisCommands gedis = GedisUtils.getInstance();
    private static ScheduledExecutorService service = new ScheduledThreadPoolExecutor(1);

    public static void startup() {
        try {
            // 第二个参数为首次执行的延时时间,第三个参数为定时执行的间隔时间
            service.scheduleAtFixedRate(() -> {
                boolean lock = new ZKLock("heartbeat" + EventBaseConstants.SEPARATOR + "redis").getLock();
                if (lock) {
                    try {
                        LocalLog.info("", "redis发布订阅=>发布心跳信息");
                        MyPublisher.publish("MyChannel",
                                "heart");

                    } catch (Exception e) {
                        LocalLog.error("redis发布订阅维持心跳任务执行异常", e);
                    }
                }
            }, 0, 1, TimeUnit.MINUTES);

        } catch (Exception e) {
            LocalLog.error("redis发布订阅维持心跳任务执行异常", e);
        }
    }

    public static void shutdown() {
        service.shutdownNow();
    }
}


java redis 发布订阅 redis实现发布订阅_redis