1.基本介绍

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

Redis 客户端可以订阅任意数量的频道。

publish(发布命令)

API:publish channel message #发布一条消息到制定频道

演示:

127.0.0.1:6379> publish cctv:5 "hello world"
(integer) 0 #订阅者个数

subscribe(订阅)

API:subscribe [channel] #订阅一个或多个频道

演示:

开启两个客户端,一个客户端先订阅cctv:5这个频道,另一个客户端往这个频道发送消息,订阅者会接收到消息。

unsubcribe(取消订阅)

API:unsubcribe [channel] #取消订阅一个或多个频道

演示:

127.0.0.1:6379> unsubscribe cctv:5
1) "unsubscribe"
2) "cctv:5"
3) (integer) 0

其它常用API

psubscribe [pattern...]  #订阅模式
punsubscribe [pattern...] #退订制定的模式
pubsub channels #列出至少有一个订阅者的模式
pubsub numsub [channel...] #列出给定频道的订阅者数量
pubsub numpat #列出被订阅模式的数量

2.SpringBoot实现redis的订阅模式

(1)导入依赖

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>

(2)配置redis

spring:redis:host: localhostport: 6379

(3)redis监听配置

@Configuration
@AutoConfigureAfter({RedisReceiver.class})
public class RedisListenerConfig {/*** redis消息监听器容器* 可以添加多个监听不同话题的redis监听器,只需要把消息监听器和相应的消息订阅处理器绑定,该消息监听器* 通过反射技术调用消息订阅处理器的相关方法进行一些业务处理** @param connectionFactory* @param listenerAdapter* @return*/@BeanRedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,MessageListenerAdapter listenerAdapter) {RedisMessageListenerContainer container = new RedisMessageListenerContainer();container.setConnectionFactory(connectionFactory);
​//可以添加多个 messageListenercontainer.addMessageListener(listenerAdapter, new PatternTopic("test"));
​return container;}
​
​/*** 消息监听器适配器,绑定消息处理器,利用反射技术调用消息处理器的业务方法** @param redisReceiver* @return*/@BeanMessageListenerAdapter listenerAdapter(RedisReceiver redisReceiver) {System.out.println("消息适配器进来了");return new MessageListenerAdapter(redisReceiver, "receiveMessage");}
​/*** 使用默认的工厂初始化redis操作模板** @param connectionFactory* @return*/@BeanStringRedisTemplate template(RedisConnectionFactory connectionFactory) {return new StringRedisTemplate(connectionFactory);}
}

(4)消息处理类

@Component
public class RedisReceiver {/*** 这里是收到通道的消息之后执行的方法** @param message*/public void receiveMessage(String message) {System.out.println("消息来了:" + message);}
}
​

(5)测试类

@EnableScheduling
@Component
public class TestController {@Autowiredprivate StringRedisTemplate stringRedisTemplate;
​/*** 向redis消息队列test通道发布消息*/@Scheduled(fixedRate = 1000)public void sendMessage() {stringRedisTemplate.convertAndSend("test", String.valueOf(Math.random()));}
​
}

测试结果如下:

消息来了:0.07573790224258636
消息来了:0.6782217218490485
消息来了:0.04274004820156474
消息来了:0.01991680494899495
消息来了:0.21214175193928786
消息来了:0.8152357687137979

(6)实现一个方法监听多个频道

    @BeanRedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,MessageListenerAdapter listenerAdapter) {RedisMessageListenerContainer container = new RedisMessageListenerContainer();container.setConnectionFactory(connectionFactory);
​//可以添加多个 messageListenercontainer.addMessageListener(listenerAdapter, new PatternTopic("test"));container.addMessageListener(listenerAdapter, new PatternTopic("test2"));
​return container;}

这样之前的receiveMessage方法会接收到来自test和test2两个频道的所有消息。

(7)实现不同方法监听不同频道

修改我们的配置类,增加消息的适配器参数,之前只有一个适配器参数,现在我们增加到两个。并把test3的频道交给第二个适配器接收。

    @BeanRedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,MessageListenerAdapter listenerAdapter,MessageListenerAdapter listenerAdapter2) {RedisMessageListenerContainer container = new RedisMessageListenerContainer();container.setConnectionFactory(connectionFactory);
​//可以添加多个 messageListenercontainer.addMessageListener(listenerAdapter, new PatternTopic("test"));container.addMessageListener(listenerAdapter, new PatternTopic("test2"));container.addMessageListener(listenerAdapter2, new PatternTopic("test3"));
​return container;}@BeanMessageListenerAdapter listenerAdapter(RedisReceiver redisReceiver) {System.out.println("消息适配器进来了");return new MessageListenerAdapter(redisReceiver, "receiveMessage");}
​@BeanMessageListenerAdapter listenerAdapter2(RedisReceiver redisReceiver) {System.out.println("消息适配器2进来了");return new MessageListenerAdapter(redisReceiver, "receiveMessage2");}

测试方法:

@EnableScheduling
@Component
public class TestController {@Autowiredprivate StringRedisTemplate stringRedisTemplate;
​/*** 向redis消息队列test通道发布消息*/@Scheduled(fixedRate = 1000)public void sendMessage() {stringRedisTemplate.convertAndSend("test", String.valueOf(Math.random()));stringRedisTemplate.convertAndSend("test2", "hello world");}
​@Scheduled(fixedRate = 1000)public void sendMessage2() {stringRedisTemplate.convertAndSend("test3", "hello redis");}
​
}

测试结果如下:

消息来了:0.21550984623295588
消息来了:hello world
消息来了2:hello redis
消息来了:0.4472284248403804
消息来了:hello world
消息来了2:hello redis
消息来了:0.3441512587764187
消息来了:hello world
消息来了2:hello redis

Redis的发布订阅模式以及在SpringBoot中的使用相关推荐

  1. SpringBoot整合redis实现发布订阅模式

    Redis的发布订阅模式 发布订阅(Pub/Sub):目前广泛使用的通信模型,它采用事件作为基本的通信机制,提供大规模系统所要求的松散耦合的交互模式:订阅者(如客户端)以事件订阅的方式表达出它有兴趣接 ...

  2. Redis的发布订阅模式

    本文源码参看:https://github.com/duktig666/learn-example/tree/5586febea31c2fb368e19fbdba11ed08afd463e0/Redi ...

  3. 发布订阅模式,在工作中它的能量超乎你的想象

    不同的语言-相同的模式 最近在看设计模式的知识,而且在工作当中,做一些打点需求的时候,正好直接利用了发布订阅模式去实现的,这让我对发布订阅这种设计模式更加的感兴趣了,于是借此机会也和大家说说这个好东东 ...

  4. 使用redis的发布订阅模式实现消息队列

    配置文件 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://w ...

  5. Redis 笔记(10)— 发布订阅模式(发布订阅单个信道、订阅信道后的返回值分类、发布订阅多个信道)

    1. 发布-订阅概念 发布-订阅 模式包含两种角色,分别为发布者和订阅者. 订阅者可以订阅一个或者若干个频道(channel): 而发布者可以向指定的频道发送消息,所有订阅此频道的订阅者都可以收到此消 ...

  6. redis发布/订阅模式

    其实在很多的MQ产品中都存在这样的一个模式,我们常听到的一个例子 就是邮件订阅的场景,什么意思呢,也就是说100个人订阅了你的博客,如果博主发表了文章,那么100个人就会同时收到通知邮件,除了这个 场 ...

  7. redis集群的发布订阅模式

    项目开发过程中,遇到需要发消息的情况,是不是脑海里不自主的浮现kafka.rabbitmq等常用的消息队列?但如果消息非常简单,并且用量也不大,消息队列就会有点大材小用了吧,忽然想起了redis 也有 ...

  8. Spring Boot 使用Redis发布订阅模式处理消息

    Spring Boot 使用Redis发布订阅模式 1. Redis发布订阅模式 2. Spring Boot中订阅消息 2.1 Redis监听器容器配置 2.2 创建通道监听器 2.3 测试订阅功能 ...

  9. java 阅发布模式_redis发布订阅模式

    一 前言 虽然有消息队列,我们还是要了解一下redis发布订阅模式哟!!!!! 二发布订阅模式 PUBLISH 命令向通道发送信息,此客户端称为publisher 发布者: SUBSCRIBE 向命令 ...

最新文章

  1. 软件架构师证书有用吗_健康管理师证书在求职时有用吗?
  2. Matlab Robotic Toolbox V9.10工具箱(七):Stanford arm 动力学建模与仿真
  3. throw throws 区别
  4. 性能测试测试环境与生产环境_不在生产中测试? 在生产中进行测试!
  5. 算法分析:Oracle 11g 中基于哈希算法对唯一值数(NDV)的估算
  6. 刚接触Cisco认证:CCNA学习经验
  7. Android:学习路线总结,绝对干货
  8. [转]网上整理 Web JS 通用
  9. RunLoop运行循环机制
  10. python教程简书_python教程
  11. 变电站综合自动化系统是将变电站内的二次设备经过功能的组合和优化设计
  12. linux ps1 主机名 ip,Bash Shell PS1: 自定义你的linux提示符十例
  13. 微信二次开发sdk非ipad/android协议(很好用)
  14. 实现西门子S71200/1500与三菱FX系列PLC通讯
  15. 【程序猿的黑科技】一些有趣且有用的的工具整理
  16. 实训——基于大数据Hadoop平台的医疗平台项目实战
  17. 二进制文件方式安装k8s 1.21
  18. Performing Basic Amazon S3 Bucket Operations
  19. 想要用Python写爬虫但是BeautifulSoup库出锅肿么办?
  20. vue国际化(不刷新页面)

热门文章

  1. Shell编程之case语句
  2. [gic]-ARM gicv2和gicv3的中断模型总结
  3. 使数据区“可执行”的几种常规办法
  4. recyclerview滑动到顶部和底部监听+上滑下滑监听
  5. 编译器扩展SEH(2)
  6. Windows内核实验003 再次回到中断
  7. 【Laravel】只保留Auth::routes()的登录,关闭Auth::routes()的注册、重置密码、验证路由
  8. 11、MySQL常见错误代码一览表
  9. bs4之标签树的平行遍历
  10. 寒假每日一题2022【week1 完结】