首页 > 数据库 >Redis发布订阅

Redis发布订阅

时间:2023-12-25 19:31:58浏览次数:35  
标签:订阅 频道 String Redis 发布 消息 new public

Redis的发布订阅(Pub/Sub)是一种消息传递模式,允许消息的发布者(publisher)将消息发送给订阅者(subscriber)。

基本概念:

  1. 发布者(Publisher):发布消息的客户端。
  2. 订阅者(Subscriber):接收并处理发布者发送的消息的客户端。
  3. 频道(Channel):消息被发布到的特定通道。发布者将消息发布到指定频道,接受者从频道获取消息。

1、相关命令

订阅频道subscribe aaaMsg aaaMsg为自定义的频道的名称。

Redis发布订阅_发布订阅

也可以同时订阅多个频道 subscribe aaaMsg bbbMsg

发布消息publish aaaMsg 123456 aaaMsg为频道名称,123456为发布消息的内容

Redis发布订阅_发布订阅_02

"1" 标识有一个订阅者接收到了信息

基于模式的频道订阅psubscribe aaa? bbb* ccc?*

Redis发布订阅_发布订阅_03

其中 ? 表示任意一个字符。 * 表示0个或任意多个字符。显然 ?* 就表示一个或任意多个字符

2、Jedis发布订阅

Jedis是Java中的Redis客户端,如何通过Jedis完成上述发布订阅过程呢?

添加依赖:

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>3.7.1</version>
</dependency>
public class Main {
    public static void main(String[] args) throws IOException {
        String host = "xxx.xxx.xxx.xxx";
        String pass = "xxxxx";

        Jedis jedis = new Jedis(host, 6379);
        jedis.auth(pass);

        // 订阅会阻塞线程
        new Thread(()->{
            jedis.subscribe(new JedisPubSub() {
                @Override
                public void onSubscribe(String channel, int subscribedChannels) {
                    System.out.println("订阅的频道: "+channel+", 当前jedis实例已订阅的频道数: "+subscribedChannels);
                }

                @Override
                public void onMessage(String channel, String message) {
                    System.out.println(channel+" :: "+message);
                }
            },"aaaMsg", "bbbMsg");
        }).start();

        // 注意一个 jedis 连接发起订阅后就不能执行 (P)SUBSCRIBE / (P)UNSUBSCRIBE / PING / QUIT 之外的命令了
        Jedis jedis2 = new Jedis(host, 6379);
        jedis2.auth(pass);
        jedis2.publish("aaaMsg","消息内容xxxxx");
    }
}

3、SpringBoot中使用发布订阅

创建消息监听器:

@Component
public class MyMsgListener implements MessageListener {

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public void onMessage(Message message, byte[] pattern) {
        System.out.println("消息来自频道:"+new String(message.getChannel()));
        // springboot 中消息是可以传递对象的,所以收到的是消息序列化后的二进制码
        // 由于没有自定义redis的序列化方式可以通过下面的方式获取默认的
        RedisSerializer defaultSerializer = redisTemplate.getValueSerializer();
        // 当然默认的就是 JdkSerializationRedisSerializer ,自己new一个也行
//        JdkSerializationRedisSerializer defaultSerializer = new JdkSerializationRedisSerializer();
        System.out.println("消息内容:"+defaultSerializer.deserialize(message.getBody()));
        System.out.println("命中频道的规则"+new String(pattern));
    }
}

配置监听器:

@Configuration
public class RedisConfig {
    @Bean
    public RedisMessageListenerContainer redisMessageListenerContainer(MyMsgListener myMsgListener, RedisConnectionFactory factory){
        // 监听器需要放到容器中
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(factory);
        // PatternTopic 为模式的频道订阅(可以使用通配符),ChannelTopic为普通频道
        container.addMessageListener(new MessageListenerAdapter(myMsgListener), List.of(new PatternTopic("aaaMsg*"), new ChannelTopic("bbb")));
        return container;
    }
}

发送消息:

@SpringBootApplication
public class App implements CommandLineRunner {

    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public void run(String... args) throws Exception {
        redisTemplate.convertAndSend("aaaMsg", "123456");
    }
}

运行结果:

Redis发布订阅_发布订阅_04

4、Redis发布订阅的特点

消息不会持久化

发布消息后就算没有订阅者接收,消息也会失效。就算之后再有订阅者订阅此频道,之前的消息也不会发送给他。故而redis的发布订阅适用于「实时但是可靠性要求不高的场景」。

消息可以跨库传播

如A服务连接1号数据库,B服务连接2号数据库,在A服务中发布消息,在B服务中的订阅者依然可以收到信息。

此特性可用于跨库缓存删除。如A服务维护Student数据(crud),B服务则是使用Student数据进行其他业务逻辑。两者属于不同的项目可能各自采用不同的数据库。这时就可以通过发布订阅解决缓存删除问题。


标签:订阅,频道,String,Redis,发布,消息,new,public
From: https://blog.51cto.com/sysh/8971404

相关文章

  • Redis分布式锁
    1.分布式锁的方案分类方案原理优点缺点基于数据库mysql数据库表的唯一索引1.表创建唯一索引2.加锁:执行insert语句,成功则加锁成功,失败则加锁失败3.解锁:执行delete语句完全利用DB实现,实现简单1.锁无超时自动失效机制,有死锁风险2.不支持锁冲入,不支持阻塞等待3.操作数据......
  • 在arm架构的银河麒麟系统部署Redis
    以下是在arm架构的银河麒麟系统上部署Redis的详细步骤:1.创建文件夹首先,在合适的位置创建必要的文件夹。在本例中,我们将创建/opt/redis和/usr/src/redis两个文件夹。mkdir/opt/redismkdir/usr/src/redis2.准备Redis及其依赖库移动redis-6.2.12.tar.gz到/usr/src/redis......
  • Redis分布式锁实现方案
    2023.12.25 今天和宝宝复盘吵架,宝宝明明错了还不承认,希望她以后能有长进。 Redis的几种数据类型String最多存储512M数据List setSortedSet有序集合Hashs哈希 Redis的几种内存淘汰策略noeviction内存满了就报错,并执行扩充可用内存命令LRU 回收最少使用的键......
  • 微软官方发布的C#开源、免费、实用的Windows工具箱
    微软官方发布的C#开源、免费、实用的Windows工具箱 思维导航前言项目介绍系统要求支持语言主要功能工具安装项目源代码部分功能截图项目源码地址优秀项目和框架精选DotNetGuide技术社区交流群前言今天分享一款由微软官方发布的C#开源、免费、实用的Windows......
  • Docker部署Redis7.X版本Cluster模式三主三从集群
    前言:最近给客户部署项目提供三台机器,需要用到redis就想着部署RedisCluster模式集群,但是找遍了csdn都没找到我想要的。花了好久参考了很多博主的帖子终于让我搞出来了,个人比较菜各位看官老爷见笑。话不多说开搞!!!!!!安装前准备:1.在三台机器上分别创建对应配置文件夹,一台机器两个节点(一......
  • 架构与思维:如何应对Redis热Key?
    ★Redis系列文章Redis系列1:深刻理解高性能Redis的本质Redis系列2:数据持久化提高可用性Redis系列3:高可用之主从架构Redis系列4:高可用之Sentinel(哨兵模式)Redis系列5:深入分析Cluster集群模式追求性能极致:Redis6.0的多线程模型追求性能极致:客户端缓存带来的革命Redis系列8......
  • 从Redis读取.NET Core配置
    在本文中,我们将创建一个自定义的.NETCore应用配置源和提供程序,用于从Redis中读取配置。在此之前,您需要稍微了解一些.NETCore配置提供程序的工作原理,相关的内容可以在Microsoft开发者官网搜索到。另外您可能还需要了解一些Redis的基础知识,比如Redis的基础数据类型,持久化等等。一......
  • 标准赋能科技创新 | 东舟主导起草的两项中关村标准正式批准发布!
    近日,由北京东舟技术股份有限公司主导起草的中关村标准《智能终端触控性能测试用机器人技术规范》与《智能终端显示流畅性测试用机器人技术规范》正式批准发布!“中关村标准”是在国家标准化委员会和工信部支持下,由中关村标准化协会发布的以自主研发技术为核心、促进产业发展......
  • 强大的VS插件CodeRush全新发布v23.2——支持并发.NET类型
    CodeRush是一个强大的VisualStudio.NET插件,它利用整合技术,通过促进开发者和团队效率来提升开发者体验。CodeRush能帮助你以极高的效率创建和维护源代码。Consume-first申明,强大的模板,智能的选择工具,智能代码分析和创新的导航以及一个无与伦比的重构集,在它们的帮助下能够大大的......
  • java操作redis
     springdataredis对jedis和lettuce进行了封装SpringDataRdis使用方式 ......