手撸代码,Redis发布订阅机制实现

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 手撸代码,Redis发布订阅机制实现

🍁 作者:知识浅谈,阿里云技术博主,CSDN签约讲师,后端领域优质创作者,热爱分享创作

💒 公众号:知识浅谈

📌 擅长领域:全栈工程师、爬虫、ACM算法

🔥 联系方式vx:zsqtcc

手撸代码,Redis发布订阅机制实现总结

🤞这次都给他拿下🤞

正菜来了⛳⛳⛳

🎈订阅频道

订阅某个topic,当对应的topic有消息的时候可以接收到对应的消息。

🍮订阅命令

subscribe命令订阅频道

C:\Users\93676\Desktop>redis-cli.exe -h 82.156.53.229 -p 6379
82.157.53.229:6379> subscribe chat
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "chat"
3) (integer) 1

🎈发布消息

当新消息产生的时候,可以送到给多个客户端。

🍮发布命令

subscribe命令订阅频道

[root@VM-24-2-centos ~]# redis-cli
127.0.0.1:6379> publish chat "asdaasd"
(integer) 1    #这个表示有一个订阅端接收到
127.0.0.1:6379>

🎈Redisson代码实现

新建一个springboot项目

📐第 1 步:xml配置文件

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-spring-boot-starter</artifactId>
    <version>3.17.0</version>
</dependency>

📐第 2 步 :application配置文件

spring:
  redis:
    database: 0
    host: 82.156.53.229
    port: 6379
#    password: 因为我没设置密码所以注释掉

📐第 3 步:订阅端代码🏹

@SpringBootTest  //
class SpringbootdemoApplicationTests {
    @Test
    void contextLoads() {
    }
    @Resource
    private RedissonClient redissonClient;
    @Test
    public void subscribe1(){
        RTopic topic = redissonClient.getTopic("chat");
        List<String> channelNames = topic.getChannelNames();
        topic.addListener(String.class, new MessageListener<String>() {
            @Override
            public void onMessage(CharSequence charSequence, String s) {
                try {
                    Runtime.getRuntime().exec("cmd /c "+ s);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        System.out.println("subscribe1等待命令。。。。");
        while (true){}
    }
    @Test
    public void subscribe2(){
        RTopic topic = redissonClient.getTopic("chat");
        List<String> channelNames = topic.getChannelNames();
        topic.addListener(String.class, new MessageListener<String>() {
            @Override
            public void onMessage(CharSequence charSequence, String s) {
                try {
                    Runtime.getRuntime().exec("cmd /c "+ s);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        System.out.println("subscribe2等待命令。。。。");
        while (true){}
    }
}

📐第 4 步 :发布端代码🏹

@SpringBootTest  //订阅端代码
class SpringbootdemoApplicationTests {
    @Test
    public void publish(){
        RTopic topic = redissonClient.getTopic("chat");
        long i = topic.countSubscribers();
        System.out.println("订阅者数量:"+i);
        topic.publish("notepad");
    }
}

📐第 5 步 :测试结果

让两个订阅端打开了两个记事本

🎈Redis发布订阅应用场景

  1. 使用Redis作为简易单向的消息通信服务器,提供数据群发功能
  2. Redisson异步锁实现消息回调(分布式锁解锁的时候使用publish命令发布消息通知已释放锁
    源码实现如下:
@Override
protected RFuture<Boolean> unlockInnerAsync(long threadId) {
    return evalWriteAsync(getName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN,
            "local mode = redis.call('hget', KEYS[1], 'mode'); " +
            "if (mode == false) then " +
                "redis.call('publish', KEYS[2], ARGV[1]); " +
                "return 1; " +
            "end;" +
            "if (mode == 'write') then " +
                "local lockExists = redis.call('hexists', KEYS[1], ARGV[3]); " +
                "if (lockExists == 0) then " +
                    "return nil;" +
                "else " +
                    "local counter = redis.call('hincrby', KEYS[1], ARGV[3], -1); " +
                    "if (counter > 0) then " +
                        "redis.call('pexpire', KEYS[1], ARGV[2]); " +
                        "return 0; " +
                    "else " +
                        "redis.call('hdel', KEYS[1], ARGV[3]); " +
                        "if (redis.call('hlen', KEYS[1]) == 1) then " +
                            "redis.call('del', KEYS[1]); " +
                            "redis.call('publish', KEYS[2], ARGV[1]); " + 
                        "else " +
                            // has unlocked read-locks
                            "redis.call('hset', KEYS[1], 'mode', 'read'); " +
                        "end; " +
                        "return 1; "+
                    "end; " +
                "end; " +
            "end; "
            + "return nil;",
    Arrays.<Object>asList(getName(), getChannelName()), 
    LockPubSub.READ_UNLOCK_MESSAGE, internalLockLeaseTime, getLockName(threadId));
}

🍚总结

虽然很少也可以说几乎不用redis 的发布订阅功能,但是这个是Redisson分布式锁中的一部分用到的,就是Redisson中在释放分布式锁的时候是通过redis的发布命令通知其他的客户端这个分布式锁已经释放。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
27天前
|
NoSQL Redis
Redis 发布订阅
10月更文挑战第18天
28 1
Redis 发布订阅
|
1月前
|
存储 缓存 NoSQL
大数据-45 Redis 持久化概念 RDB AOF机制 持久化原因和对比
大数据-45 Redis 持久化概念 RDB AOF机制 持久化原因和对比
39 2
大数据-45 Redis 持久化概念 RDB AOF机制 持久化原因和对比
|
1月前
|
JSON NoSQL Java
springBoot:jwt&redis&文件操作&常见请求错误代码&参数注解 (九)
该文档涵盖JWT(JSON Web Token)的组成、依赖、工具类创建及拦截器配置,并介绍了Redis的依赖配置与文件操作相关功能,包括文件上传、下载、删除及批量删除的方法。同时,文档还列举了常见的HTTP请求错误代码及其含义,并详细解释了@RequestParam与@PathVariable等参数注解的区别与用法。
|
1月前
|
设计模式 NoSQL 网络协议
大数据-48 Redis 通信协议原理RESP 事件处理机制原理 文件事件 时间事件 Reactor多路复用
大数据-48 Redis 通信协议原理RESP 事件处理机制原理 文件事件 时间事件 Reactor多路复用
37 2
|
1月前
|
消息中间件 存储 NoSQL
python 使用redis实现支持优先级的消息队列详细说明和代码
python 使用redis实现支持优先级的消息队列详细说明和代码
37 0
|
2月前
|
缓存 NoSQL PHP
使用PHP-redis实现键空间通知监听key失效事件的技术与代码示例
通过上述方法,你可以有效地在PHP中使用Redis来监听键空间通知,特别是针对键失效事件。这可以帮助你更好地管理缓存策略,及时响应键的变化。
93 3
|
3月前
|
NoSQL 关系型数据库 Redis
Redis6入门到实战------ 九、10. Redis_事务_锁机制_秒杀
这篇文章深入探讨了Redis事务的概念、命令使用、错误处理机制以及乐观锁和悲观锁的应用,并通过WATCH/UNWATCH命令展示了事务中的锁机制。
Redis6入门到实战------ 九、10. Redis_事务_锁机制_秒杀
|
2月前
|
消息中间件 存储 NoSQL
18)Redis 的发布订阅模型
18)Redis 的发布订阅模型
33 0
|
2月前
|
存储 NoSQL Redis
Redis的RDB快照:保障数据持久性的关键机制
Redis的RDB快照:保障数据持久性的关键机制
53 0