1.工作原理
Redis的发布订阅(pub/sub)是一种消息通信模式,客户端指定某个频道(channel)进行消息的发布和订阅,向channel发送消息的客户端称为发布者(pub),订阅并接收消息的客户端称为订阅者(sub)。

2.存储结构

图中可看出结构与Java的HashMap类似,并且关系结构中并没有涉及到发布者,可以断定客户端可以通过命令随意向channel发送消息。当消息发送到channel后,会遍历所有订阅此channel的客户端,逐个进行消息的推送。
3.终端命令
1 2 3 4 5
| publish [channel] [message] // 向某个频道发布消息
subscribe [channel-0] [channel-1] // 订阅一个或多个频道消息
unsubscribe [channel] // 退订某频道消息
|
4.客户端命令
4.1 发布消息
RedisTemplate客户端提供了发布消息的API:
1
| redisTemplate.convertAndSend("频道名称", "消息Object");
|
4.2 接受消息
关于订阅的配置类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| @Configuration public class RedisConfig{
@Bean public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory, MessageListenerAdapter adapter) { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(connectionFactory); container.addMessageListener(adapter, new PatternTopic("频道名称1")); container.addMessageListener(adapter, new PatternTopic("频道名称2")); return container; }
@Bean public MessageListenerAdapter adapter(MessageReceiverSupport messageReceiver) { return new MessageListenerAdapter(messageReceiver, "onMessage"); } }
|
监听类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| @Component @Slf4j public class MessageReceiverSupport implements MessageListener { @Autowired private RedisTemplate<String, Object> redisTemplate;
@Override public void onMessage(Message message, byte[] pattern) { RedisSerializer<String> redisSerializer = redisTemplate.getStringSerializer(); String msg= redisSerializer.deserialize(message.getBody()); System.out.println("接收到的消息是:"+ msg); log.info("Received <" + msg + ">"); } }
|
5.与MQ的区别
Redis仅仅提供了最基础的发布订阅功能,无法做到消息的持久化、重试等可靠机制,消息丢失概率较大,不适用消息密集或者可靠性要求很高的场景,甚至说有些鸡肋。另外各种MQ提供的负载均衡、消费模式、消息延迟、消息过滤、事务等可以满足各种复杂的业务场景,也是Redis无法实现的。
最后Redis的发布订阅完全基于内存操作,不过目前流行的MQ都会尽可能的将磁盘IO进行顺序读写,性能不会拉开太多差距,另外还可以通过增加队列来均摊压力,不考虑运维成本的情况下,性能也是优于Redis的。总体上说Redis发布订阅可以满足的场景,各种MQ都可以满足,因此在已经有MQ中间件的前提下,尽量不要考虑Redis的发布订阅。
6.应用场景
Redis内部的哨兵集群模式在相互监控的时候使用了此功能进行通信。