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

Redis 过期监听场景

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

redis配置

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

项目demo工程

项目结构如下图

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过期键通知内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Redis 2.8-4.0过期键优化过程全纪录

    前言 之前 白馨(陌陌-技术保障部存储工程师 )在Redis技术交流群里,总结了一下Redis从2.8~4.0关于过期键相关的fix记录,非常有帮助,但有些东西未尽详细,本文将进行详细说明. 先从一个问题来看,运行环境如下: Redis: 2.8.19 db0:keys=10000000,expires=10000000 主从结构 从下图中可以看到,在从节点get hello非空,在主节点get hello为空,之后从节点get hello为空,经排查主从同步offset基本正常,但出现了主从不

  • Redis开启键空间通知实现超时通知的步骤

    Redis部分设置 修改配置文件redis.conf(Windows为redis.windows.conf) 打开该配置文件(位置取决于自己的安装位置),找到Event notification部分. 将notify-keyspace-events Ex的注释打开或者添加该配置,其中E代表Keyevent,此种通知会返回key的名字,x代表超时事件. 如果notify-keyspace-events ""配置没有被注释的话要注释掉,否则不会生效. 保存后重启redis,一定要使用当前配

  • redis键空间通知使用实现

    目录 导语 实现 在业务中使用 总结 导语 最近在开发一个定时活动,而且活动是多个场次的.这个是后就需要在活动开始的时候推送信息给客户端,结束的时候也要推送一次.简单的设计方案就是将配置缓存在redis,然后每隔一秒就轮询reids,获取配置信息,然后判断是不是到活动开始或者结束的时间点,然后推送给客户端. 但是,这里会有一个问题,如果没有到活动开始或结束的时间点,这里会造成很多无用的轮询操作.这个操作不但增大了对这个key的访问量,同时也会占用cpu,降低机器性能. redis在2.8.0版本

  • 大家都应该知道的Redis过期键与过期策略

    今天,我和大家分享一篇关于 Redis 有关过期键的内容,主要有四个内容: 如何设置过期键 如何取消设置的过期时间 过期键的过期策略是怎样的 RDB.AOF 和复制对过期键的处理又是怎样的 设置键的生存时间或过期时间 redis 一共有 4 个命令来设置键的生存时间(可以存活多久)或过期时间(什么时候被删除) expire <key> <ttl>:将 key 的生存时间设置为 ttl 秒 pexpire <key> <ttl>:将 key 的生存时间设置为

  • redis学习之RDB、AOF与复制时对过期键的处理教程

    生成RDB文件 在执行SAVE命令或者BGSAVE命令创建一个新的RDB文件时,程序会对数据库中的键进行检查,已过期的键不会被保存到新创建的RDB文件中. 举个例子,如果数据库中包含三个键k1.k2.k3,并且k2已经过期,那么当执行SAVE命令或者BGSAVE命令时,程序只会将k1和k3的数据保存到RDB文件中,而k2则会被忽略. 因此,数据库中包含过期键不会对生成新的RDB文件造成影响. 可参考rdb.c中函数rdbSave()函数源码: /* Iterate this DB writing

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

    Redis 过期监听场景 业务中有类似等待一定时间之后执行某种行为的需求 , 比如 30 分钟之后关闭订单 . 网上有很多使用 Redis 过期监听的 Demo redis配置 把notify-keyspace-events Ex 这一行的注释打开 项目demo工程 项目结构如下图 maven依赖 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apa

  • 基于 Spring Aop 环绕通知实现 Redis 缓存双删功能(示例代码)

    基于 spring aop 常规应用场景多是用于日志记录以及实现 redis 分布式锁,在 github 中也有项目是把它拿来当作缓存的异常捕捉.从而避免影响实际业务的开发:在某天,笔者有个业务开发是给某个服务模块增加 redis 缓存.增加缓存就会涉及 redis 删除.所以笔者就在思考是不是可以用环绕通知的方式来进行实现 代码实现 结构示意图: 自定义注解 RedisDelByDbUpdate @Repeatable 表示允许在同一个地方上使用相同的注解,没有该注解时贴相同注解会报错 @Ta

  • Redis中过期键如何删除示例详解

    目录 前言 Redis 中 key 的过期删除策略 1.定时删除 2.惰性删除 3.定期删除 Redis 中过期删除策略 从库是否会脏读主库创建的过期键 内存淘汰机制 内存淘汰触发的最大内存 有哪些内存淘汰策略 内存淘汰算法 LRU LFU 为什么数据删除后内存占用还是很高 内存碎片如何产生 碎片率的意义 如何清理内存碎片 总结 参考 前言 Redis 中的 key 设置一个过期时间,在过期时间到的时候,Redis 是如何清除这个 key 的呢? 这来分析下 Redis 中的过期删除策略和内存淘

  • 浅谈Redis常见延迟问题定位与分析

    目录 使用复杂度高的命令 存储bigkey 集中过期 实例内存达到上限 fork耗时严重 绑定CPU 使用Swap 网卡负载过高 使用复杂度高的命令 如果在使用Redis时,发现访问延迟突然增大,如何进行排查? 首先,第一步,建议你去查看一下Redis的慢日志.Redis提供了慢日志命令的统计功能,我们通过以下设置,就可以查看有哪些命令在执行时延迟比较大. 首先设置Redis的慢日志阈值,只有超过阈值的命令才会被记录,这里的单位是微妙,例如设置慢日志的阈值为5毫秒,同时设置只保留最近1000条慢

  • Redis实现延迟队列的全流程详解

    目录 1.前言 1.1.什么是延迟队列 1.2.应用场景 1.3.为什么要使用延迟队列 2.Redis sorted set 3.Redis 过期键监听回调 4.Quartz定时任务 5.DelayQueue 延迟队列 6.RabbitMQ 延时队列 7.时间轮 1.前言 1.1.什么是延迟队列 延时队列相比于普通队列最大的区别就体现在其延时的属性上,普通队列的元素是先进先出,按入队顺序进行处理,而延时队列中的元素在入队时会指定一个延迟时间,表示其希望能够在经过该指定时间后处理.从某种意义上来讲

  • 多个SpringBoot项目采用redis实现Session共享功能

    有时我们可能有多个不同的Web应用,可以相互调用,这时如果每个应用都有自己的session,那用户跳转到另一个应用时就又需要登陆一次,这样会带来很不好的体验,因此我们需要在不同的应用中共享session.这里,我们采用redis来实现. 前置说明 由于只用到redis和springboot的整合,所以只能实现一个URL下的不同端口的应用之间的session共享,如果连应用名称都完全不同的两个应用要实现session共享,在这个基础上还需要使用到Nginx,这种方式我暂时还没有试过.(Spring

  • Go+Redis实现延迟队列实操

    目录 前言 简单的实现 定义消息 Push Consume 存在的问题 多消费者实现 定义消息 Push Consume 存在的问题 总结 前言 延迟队列是一种非常使用的数据结构,我们经常有需要延迟推送处理消息的场景,比如延迟60秒发送短信,延迟30分钟关闭订单,消息消费失败延迟重试等等. 一般我们实现延迟消息都需要依赖底层的有序结构,比如堆,而Redis刚好提供了zset这种数据类型,它的底层实现是哈希表+跳表,也是一种有序的结构,所以这篇文章主要是使用Go+Redis来实现延迟队列. 当然R

  • php+redis实现商城秒杀功能

    好久没来整理文章了,闲了没事写篇文章记录下php+redis实现商城秒杀功能. 1.安装redis,根据自己的php版本安装对应的redis扩展(此步骤简单的描述一下) 1.1.安装php_igbinary.dll,php_redis.dll扩展此处需要注意你的php版本如图: 1.2.php.ini文件新增extension=php_igbinary.dll;extension=php_redis.dll两处扩展 ok此处已经完成第一步redis环境搭建完成看看phpinfo 2.项目中实际使

随机推荐