关于Redis的事件回调解析以及docker中的配置

2023-11-20

基本概念

Redis的过期回调可以实现我们的redsi的key在过期的时候回调一些接口从而来实现项目中需要的一些功能。比如我们想在订单超时的时候进行关闭,可以用这个来进行一个简单的实现,当然实际的项目中能否这样使用我们暂且不做讨论,这里只是举个例子。

Redis的事件回调的特点

  • Redis的过期回调底层是根据Redis的发布订阅实现的,通过订阅特定的频道,实现某些节点过期了之后向特定的频道发送消息,触发回调的功能。
  • 不能保证可靠性,因为Redis的事件回调是基于发布订阅实现的,而发布订阅是发送即忘,所以如果我们项目中需要可靠的回调,就不能使用这种方式。当订阅事件的客户端断线时, 它会丢失所有在断线期间分发给它的事件。另外redis的过期也并不是保证能够实时过期,2.4之前过期时间的误差官方文档说的是0-1秒,2.4之后是0-1毫秒。
  • Redis的事件回调不仅仅是过期回调,可以是很多其他的命令的回调,这个部分可以参考
  • 所有命令都只在键真的被改动了之后,才会产生通知。例如试图删除不存在于集合的元素时,删除操作会执行失败,因为没有真正的改动键,所以这一操作不会发送通知。

Redis是怎么实现过期的?

redis的过期是根据上次更新时间和当前时间的差值,比较看是否大于设置的过期时间,大于就过期。但是redis服务宕机了之后设置了过期时间的key如果还没有过期,就会导致过期时间失效,变成永久的key。
另外要注意,redis过期的key不会立马删除,因为redis采用定时删除和惰性删除,有可能到了过期时间但是key还没有删除,这个时候我redis宕机了,重启之后即使是已经过期了的key也会变成永久的。

过期事件回调的应用实战

首先打开redis的配置文件,然后将notify-keyspace-events Ex这个配置的注释打开,由于打开这个回调的通知会对redis的性能有一定的影响,所以官方默认是关闭的。这个Ex参数的作用就是生命是过期事件才进行发布通知。

然后引入依赖

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <version>2.1.9.RELEASE</version>
        </dependency>

创建配置类

package com.dongmu.config;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;

@Configuration
public class RedisConfiguration {
    @Autowired
    private RedisConnectionFactory redisConnectionFactory;

    @Bean
    public ChannelTopic expireTopic(){
        return new ChannelTopic("test01");
    }

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

这里说明一下为什么需要这个配置类RedisMessageListenerContainer ,这个类在我们下面创建一个监听器类的时候需要用到这个对象作为入参,所以必须创建,不然由于构造函数参数缺少没无法创建监听器bean对象。

创建监听器bean对象

package com.dongmu.listener;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component;

@Component
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {
    public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }


    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Override
    public void onMessage(Message message,byte[] pattern){
        String expireKey = message.toString();
        System.out.println(expireKey);

        if (expireKey.startsWith("dongmu:test")){
            System.out.println(expireKey+"过期了");
        }
    }
}

onMessage方法里面可以处理我们的逻辑。

下面编写一个Controller进行测试

@Autowired
    StringRedisTemplate redisTemplate;
    @RequestMapping("/redis/test")
    public void RedisTest(){
        redisTemplate.opsForValue().set("dongmu:test:key1","mytestkey1",5, TimeUnit.SECONDS);
    }

访问接口
在这里插入图片描述
结果
在这里插入图片描述
可以发现这里的过期通知生效了。

redis的过期回调实现订单的超时关闭

redis的过期回调并不能够保存可靠性,所以一般不能这样用,如果这样用的话还要定时扫描数据库处理已经超时的订单,不能完全依靠redis的过期回调通知,另外redis 的过期时间有可能变成永久的,而且开启了过期回调会影响redis的性能,所以尽量不要这样用,小项目的话可以尝试以下,大项目的或者要求比较高的场景一定要使用专业的消息中间件。

docker中配置redis

一般我们的linux服务器上的redis可能会安装在docker容器内部,这个时候想要修改容器中redis的配置就需要做挂载,步骤如下:

docker pull redis #下载最新版本的redis
#下面这一步会把我们的内部的文件夹挂载到外部文件夹以及映射的端口,
#要注意这个命令里面指定了配置文件
docker run -p 9999:6379 --name redis -v /usr/local/docker:/etc/redis -v /usr/local/docker/data:/data -d redis redis-server /etc/redis/redis.conf --appendonly yes

#然后我们利用下载最新的redsi的配置文件,在配置文件中指定redis的密码,
#注意这里配置文件一定要用和这个版本一致的配置文件不然还会报错
requirepass ***(这里写你的密码)
maxclients 1000(最大的连接数量)

#同时把过期回调的注释打开
notify-keyspace-events Ex

#配置好了之后我们启动docker 中的redis容器即可
dockers start 容器id

亲测服务器上过期回调成功
在这里插入图片描述

在这里插入图片描述
对于已经启动的redis我们还可以查看docker的配置

docker inspect redis #即可查看
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

关于Redis的事件回调解析以及docker中的配置 的相关文章

  • 同一服务器上的许多应用程序具有相同的 JMX Mbean 类

    我有超过 5 个 Spring Web 应用程序 它们都在使用另一个通用库 这个公共库有它自己的 MBean 由于强制的唯一 objectName 约束 我的应用程序无法部署在同一服务器上 我使用 MBean 的方式是这样的 Managed
  • “源兼容性”和“目标兼容性”有什么区别?

    之间有什么关系 区别sourceCompatibility and targetCompatibility 当它们设置为不同的值时会发生什么 根据工具链和兼容性 https docs gradle org current userguide
  • 非易失性领域的出版与阅读

    public class Factory private Singleton instance public Singleton getInstance Singleton res instance if res null synchron
  • 以相反的顺序打印任何集合中的项目?

    我在 使用 Java 进行数据结构和问题解决 一书中遇到以下问题 编写一个例程 使用 Collections API 以相反的顺序打印任何 Collection 中的项目 不要使用 ListIterator 我不会把它放在这里 因为我想让有
  • 如何使用 Java Apache POI 隐藏 Excel 工作表中以下未使用的行?

    我正在使用数据库中的数据填充模板 Excel 工作表 for Map
  • getCurrentSession 在网络中休眠

    我正在使用 hibernate 和 jsp servlet 编写一个基于 Web 的应用程序 我读过有关sessionFactory getCurrentSession and sessionFactory openSession方法 我知
  • 如何使用双重调度来分析图形基元的交集?

    我正在分析图形基元 矩形 直线 圆形等 的交互并计算重叠 相对方向 合并等 这被引用为双重调度的一个主要示例 例如维基百科 http en wikipedia org wiki Double dispatch 自适应碰撞算法通常要求 不同的
  • 如何在 IntelliJ IDEA 中运行 akka actor

    来自 Akka 网站文档 然后 这个主要方法将创建所需的基础设施 运行演员 启动给定的主要演员并安排 一旦主要参与者终止 整个应用程序就会关闭 因此 您将能够使用类似于以下的命令运行上面的代码 下列的 java classpath akka
  • Android 认为我没有关闭数据库!为什么?

    我有一个 SQLiteDatabase 数据成员 我在 onCreate 中初始化它 并在 onPause onStop 和 onDestroy 中调用 close 它在 onResume 中重新初始化 它似乎运行得很好 但当我查看调试器时
  • 使用 Proguard 通过 Dropbox.com 库混淆 Android 应用程序

    我刚刚创建了一个需要 Dropbox com API 库的 Android 应用程序 我现在尝试在 发布 模式下构建应用程序 并希望在代码上运行混淆器以对其进行混淆 但是 每当我尝试运行 Proguard 时 都会收到以下错误 Progua
  • Java 8 Stream,获取头部和尾部

    Java 8 引入了Stream http download java net jdk8 docs api java util stream Stream html类似于 Scala 的类Stream http www scala lang
  • 按降序排序映射java8 [重复]

    这个问题在这里已经有答案了 private static
  • 如何向页面添加 HTML 页眉和页脚?

    如何使用 itext 从 html 源添加标题到 pdf 目前 我们已经扩展了 PdfPageEventHelper 并重写了这些方法 工作正常 但当我到达 2 个以上页面时 它会抛出 RuntimeWorkerException Over
  • 如何使用 Jersey 将嵌套列表封送为 JSON?我得到一个空数组或一个包含数组的单元素字典数组

    我正在开发一个使用 Jersey 将对象转换为 JSON 的项目 我希望能够写出嵌套列表 如下所示 data one two three a b c 我想要转换的对象首先将数据表示为 gt gt 我认为 Jersey 会做正确的事情 以上输
  • Lombok 不适用于 Eclipse Neon

    我下载了lombok jar lombok 1 16 14 jar 并将其放入我的下载中 然后我点击这个 jar 执行正确地识别了我的 MacOS 上的 Eclipse 实例 然后我选择了我想要的实例 Lombok也在pom xml中指定
  • Android计算两个日期之间的天数

    我编写了以下代码来查找两个日期之间的天数 startDateValue new Date startDate endDateValue new Date endDate long diff endDateValue getTime star
  • Android ScrollView,检查当前是否滚动

    有没有办法检查标准 ScrollView 当前是否正在滚动 方向是向上还是向下并不重要 我只需要检查它当前是否正在滚动 ScrollView当前形式不提供用于检测滚动事件的回调 有两种解决方法可用 1 Use a ListView并实施On
  • 确定 JavaFX 中是否消耗了事件

    我正在尝试使用 JavaFX 中的事件处理来做一些非滑雪道的事情 我需要能够确定手动触发事件后是否已消耗该事件 在以下示例中 正确接收了合成鼠标事件 但调用 Consumer 不会更新该事件 我对此进行了调试 发现 JavaFX 实际上创建
  • 检测到 JVM 正在关闭

    我有一个使用 addShutdownHook 处理 Ctrl C 的 Swing 应用程序 它工作正常 直到我的关闭任务之一调用一个在正常情况下更改 JLabel 文本的函数 此时它挂起 我认为问题是 Swing EDT 已终止或正在等待某
  • 什么是 Java2D 处理程序线程?

    我创建了一个使用 Hibernate 的示例 java 应用程序 当我进行线程转储时 我观察到一个名为 Java2D Disposer 的奇怪线程 有人能告诉我该线程的功能吗 AWT 系统中的某些实体需要最终确定以释放资源 最突出的例子是j

随机推荐

  • 机器学习入门——线性代数简单回顾

    本节课程回顾了一些简单但常用的线性代数知识 很基础的 我会直接跳过 并对矩阵的一些运算进行编程实现 3 1 矩阵的加法和标量乘法 矩阵加法 要求行列数要相等 然后 每个元素对应相加 exp 矩阵的标量乘法 每个元素都要乘 exp 3 2 矩
  • 深入理解数据结构——堆栈应用(四染色算法)

    include
  • 宿舍报修平台的小程序实现

    5 26 修改内容 加入了项目结构化需求分析 6 2 修改内容 加入了产品设计原型图以及产品项目进度 6 9 修改内容 加入了用例图 静态UML图 动态UML图 目录 项目背景 需求调查 数据采样 项目目标 项目前景 项目评估 项目范围 项
  • Solving environment: failed with initial frozen solve. Retrying with flexible solve.

    使用conda安装pytorch老是失败 于是使用以下命令安装pytorch conda install pytorch torchvision cudatoolkit 10 1 下载成功
  • 几种表面缺陷检测数据集

    2020 05 23更新 在github上创建了一个缺陷数据的项目 以后也会更新 谢谢加星 2021 09 13 我建了一个表面缺陷检测的qq交流群657617577 欢迎大家入圈交流 GitHub Eatzhy Surface defec
  • 长春理工大学第六届CTF网络攻防大赛题解(文末有题目下载链接)

    此题解仅为部分题解 包括 RE Reverse Checkin SimplePE EzGame Web f12 ezrunner Crypto MD5 password 看我回旋踢 摩丝 Misc 爆爆爆爆 凯撒大帝的三个秘密 你才是职业选
  • R语言中tidyverse基础知识汇总

    tidyverse group by 分组统计 gather 和spread 简单地说 gather 是列转行 而spread 是行转列 请看下面的示例 gt df id class grade 1 1 a 81 2 2 b 82 3 3
  • Unity在UI界面上显示3D模型/物体,控制模型旋转

    https blog csdn net ChinarCSDN article details 81058773
  • TDengine数据库-TAOS涛思数据-批量下载上亿大数据成csv 解决bug: Query interrupted (Query terminated) 4798749 row(s) in set

    目录 前言 taos shell命令批量下载数据库遇到中断问题 分析问题 解决方案 查看tao cfg文件 使用分页下载 在合并csv 1 构建 sql文件批量进行下载 2 合并分csv文件成总csv文件 总结 其它资料下载 前言 TDen
  • ET篇:斗地主的流程(资源工作流)

    有了master的学习经验 斗地主的学习将不会太多精细化 更多细节大家可以自行查看 本系列文章旨在帮助大家理解整个开发流程 资源划分策略 先来到Asset下的Bundles文件夹 这里是游戏内用到的所有的资源 都被打成ab包 正式发布时将会
  • 「 每日一练,快乐水题 」14. 最长公共前缀

    文章目录 力扣原题 题目简述 解题思路 C 代码 结果展示 力扣原题 14 最长公共前缀 题目简述 编写一个函数来查找字符串数组中的最长公共前缀 如果不存在公共前缀 返回空字符串 示例 1 输入 strs flower flow fligh
  • 一键设置L2TP脚本-Ubuntu14.04LTS

    亲测在Vultr和UltraVPS的Ubuntu 14 04 LTS成功搭建L2TP的VPN 本方法使用Linux自带的账户认证作为L2TP的认证 用户名默认为vpn user 密码在脚本执行过程中 由执行者手动设定密码 PSK为psk 开
  • linux中安装nginx

    2 安装nginx 2 1 安装nginx前 需要安装的依赖 可能是由于nginx版本旧原因 可能最新或较新版本不需安装这些依赖 如下四个依赖需要安装到linux中 2 1 1 安装 pcre 依赖 使用wget命令 步骤一 执行下面这个命
  • Debug断点无法执行

    1 可能是没有启动debug模式 导致无法进入 2 可能是idea中有缓存 导致直接出结果 这种选择重新启动项目即可
  • 浅谈core.js

    浅谈core js core js 前言 core js是什么 官方描述 总结 core js 前言 core js的作者 Denis Pushkarev 很有名 平时爱好就是飙摩托车 在一次事故中 酒驾 他以60km h的速度驾驶 结果撞
  • 2.5 Git 基础 - 远程仓库的使用

    2 5 Git 基础 远程仓库的使用 版本说明 版本 作者 日期 备注 0 1 loon 2019 3 21 初稿 目录 文章目录 2 5 Git 基础 远程仓库的使用 版本说明 目录 远程仓库的使用 1 查看远程仓库 2 添加远程仓库 3
  • 【大屏可视化模板】vue-dataV-echarts-elementul大屏数据可视化方案,屏幕适配方案等比例缩放

    效果图 从上到下 依次是F11效果 和正常网页效果 以及小屏效果 都是同比例缩放的 布局不会混乱 聊一下 为了让大家直观的看到所有的代码 所以结构方法等就不分各个组件引入了 会很麻烦要找哪是哪 我直接把所有的图都写在了一个vue组件内 并配
  • 电脑有网但打不开网页怎么办?

    明明刚交了宽带年费 本地连接显示一切正常 但是打开网页总有问题 换浏览器重启无效 我该怎么办 放心吧 下面 微点阅读小编整理了一些网络链接正常却上不了网的解决方法 对于经常上网的朋友来说 除了手机购物 在Pc端玩网页游戏是很多小伙伴的首选
  • idea 启动时怎么选择工作空间

    idea 启动时怎么选择工作空间 按快捷键 ctrl alt s打开设置 点击System Settings选项后 把右边版面中Reopen last projecton startup前面的勾去掉 保存 下次再打开的时候就可以选择你要的空
  • 关于Redis的事件回调解析以及docker中的配置

    基本概念 Redis的过期回调可以实现我们的redsi的key在过期的时候回调一些接口从而来实现项目中需要的一些功能 比如我们想在订单超时的时候进行关闭 可以用这个来进行一个简单的实现 当然实际的项目中能否这样使用我们暂且不做讨论 这里只是