使用redis实现延迟通知功能(Redis过期键通知)


Posted in Redis onSeptember 04, 2021

Redis 过期监听场景

业务中有类似等待一定时间之后执行某种行为的需求 , 比如 30 分钟之后关闭订单 . 网上有很多使用 Redis 过期监听的 Demo

redis配置

 把notify-keyspace-events Ex 这一行的注释打开

使用redis实现延迟通知功能(Redis过期键通知)

项目demo工程

项目结构如下图

使用redis实现延迟通知功能(Redis过期键通知)

maven依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>kim-redis</artifactId>
        <groupId>com.kim</groupId>
        <version>1.0.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>kim-redis-expiration-notice</artifactId>

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

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>

    </dependencies>
</project>

配置文件

server:
  port: 20103

spring:
  redis:
    #数据库索引
    database: 0
    host: 127.0.0.1
    port: 6379
    password: 123456
    lettuce:
      pool:
        #最大连接数
        max-active: 8
        #最大阻塞等待时间(负数表示没限制)
        max-wait: -1
        #最大空闲
        max-idle: 8
        #最小空闲
        min-idle: 0
    #连接超时时间
    timeout: 10000

启动类

/**
 * @Project: kim-redis
 * @PackageName: com.kim.redis.expiration.notice
 * @FileName: NoticeApplication.java
 * @Description: The NoticeApplication is...
 * @Author: kimwu
 * @Time: 2020-12-19 14:01:56
 */
@SpringBootApplication
public class NoticeApplication {

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

}

配置类

@Configuration
public class RedisTimeoutConfiguration {

    @Autowired
    private RedisConnectionFactory redisConnectionFactory;

    @Bean
    public RedisMessageListenerContainer redisMessageListenerContainer() {
        RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer();
        redisMessageListenerContainer.setConnectionFactory(redisConnectionFactory);
        return redisMessageListenerContainer;
    }

    @Bean
    public KeyExpiredListener keyExpiredListener() {
        return new KeyExpiredListener(this.redisMessageListenerContainer());
    }
}

监听类

@Slf4j
public class KeyExpiredListener extends KeyExpirationEventMessageListener {


    public KeyExpiredListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }

    @Override
    public void onMessage(Message message, byte[] pattern) {
        String channel = new String(message.getChannel(), StandardCharsets.UTF_8);
        //过期的key
        String key = new String(message.getBody(), StandardCharsets.UTF_8);
        log.info("redis key 过期:pattern={},channel={},key={}", new String(pattern), channel, key);
    }
}

异常情况测试

当key过期时,项目宕机了
①写入redis的key
②手动关停服务,等待redis的key过期
③确认redis的key过期后,重启服务。服务不会收到通知

当key过期时,redis服务宕机了
①写入redis的key
②关停redis服务,等待redis的key过期
③启动redis服务,发现redis的过期key已经不存在了,服务没有收到通知

结论

redis的键过期本身不可靠,并不像rabbitmq一样保证了可靠性。
当服务本身宕机或者redis宕机时,将无法保证过期的key能够被消费。

当使用场景对数据完整性不那么精确时,可以使用redis的键过期策略。否则不太建议使用redis的键过期策略。

到此这篇关于使用redis实现延迟通知功能(Redis过期键通知)的文章就介绍到这了,更多相关Redis过期键通知内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Redis 相关文章推荐
redis三种高可用方式部署的实现
May 11 Redis
基于Redis实现分布式锁的方法(lua脚本版)
May 12 Redis
基于Redis延迟队列的实现代码
May 13 Redis
Windows中Redis安装配置流程并实现远程访问功能
Jun 07 Redis
redis cluster支持pipeline的实现思路
Jun 23 Redis
Redis做数据持久化的解决方案及底层原理
Jul 15 Redis
redis 存储对象的方法对比分析
Aug 02 Redis
Redis RDB技术底层原理详解
Sep 04 Redis
Redis之RedisTemplate配置方式(序列和反序列化)
Mar 13 Redis
Redis特殊数据类型bitmap位图
Jun 01 Redis
Redis批量生成数据的实现
Jun 05 Redis
基于redis+lua进行限流的方法
Jul 23 Redis
Redis集群新增、删除节点以及动态增加内存的方法
Sep 04 #Redis
Redis字典实现、Hash键冲突及渐进式rehash详解
Sep 04 #Redis
基于Redis的List实现特价商品列表功能
Aug 30 #Redis
Redis 常见使用场景
Aug 30 #Redis
Redis入门教程详解
Redis如何实现分布式锁
Aug 23 #Redis
Redisson实现Redis分布式锁的几种方式
You might like
php中使用explode查找某个字符是否存在的方法
2011/07/12 PHP
解决form中action属性后面?传递参数 获取不到的问题
2017/07/21 PHP
如何利用预加载优化Laravel Model查询详解
2017/08/11 PHP
js验证表单第二部分
2006/11/25 Javascript
在UpdatePanel内jquery easyui效果失效的解决方法
2010/04/11 Javascript
jquery向.ashx文件post中文乱码问题的解决方法
2011/03/28 Javascript
jQuery EasyUI API 中文文档 - Parser 解析器
2011/09/29 Javascript
jquery焦点图片切换(数字标注/手动/自动播放/横向滚动)
2013/01/24 Javascript
Javascript冒泡排序算法详解
2014/12/03 Javascript
JavaScript中神奇的call()方法
2015/03/12 Javascript
jquery用ajax方式从后台获取json数据后如何将内容填充到下拉列表
2015/08/26 Javascript
深入浅析JavaScript中的3DES
2016/08/24 Javascript
获取当前月(季度/年)的最后一天(set相关操作及应用)
2016/12/27 Javascript
简单实现jQuery多选框功能
2017/01/09 Javascript
关于javascript获取内联样式与嵌入式样式的实例
2017/06/01 Javascript
jQuery实现返回顶部按钮和scroll滚动功能[带动画效果]
2017/07/05 jQuery
vue组件详解之使用slot分发内容
2018/04/09 Javascript
vue移动端监听滚动条高度的实现方法
2018/09/03 Javascript
详解JavaScript 异步编程
2020/07/13 Javascript
[56:00]2018DOTA2亚洲邀请赛 4.6 淘汰赛 VP vs TNC 第二场
2018/04/10 DOTA
[56:18]VGJ.S vs Secret 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
Python交换变量
2008/09/06 Python
python 实现矩阵上下/左右翻转,转置的示例
2019/01/23 Python
Python3实现计算两个数组的交集算法示例
2019/04/03 Python
python实现kmp算法的实例代码
2019/04/03 Python
python字符串查找函数的用法详解
2019/07/08 Python
Django项目创建到启动详解(最全最详细)
2019/09/07 Python
HTML5+CSS3:3D展示商品信息示例
2017/01/03 HTML / CSS
世界最大的海报和艺术印刷商店:AllPosters.com
2017/02/01 全球购物
Conforama西班牙:您的家具、装饰和电器商店
2020/02/21 全球购物
2015学校师德师风工作总结
2015/04/22 职场文书
公司辞职信模板
2015/05/13 职场文书
《学会看病》教学反思
2016/02/17 职场文书
Python基础之元组与文件知识总结
2021/05/19 Python
vue组件冲突之引用另一个组件出现组件不显示的问题
2022/04/13 Vue.js
docker compose 部署 golang 的 Athens 私有代理问题
2022/04/28 Servers