借助 redis 的 key 失效通知设置优惠券状态| 学习笔记

简介: 快速学习借助 redis 的 key 失效通知设置优惠券状态。

开发者学堂课程【使用 Redis 消息队列完成秒杀过期订单处理 :借助 redis 的 key 失效通知设置优惠券状态】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/729/detail/13022


借助 redis 的 key 失效通知设置优惠券状态

 

内容介绍

一.配置监听 redis 的通知

1. 定义一个消息的监听器

2.将监听类配置到 Spring 配置文件中去

3.编写测试

 

一、配置监听 redis 的通知

Coupon-achieve 中创建好了一张优惠券,并且存入到数据库,同时再 redis 设置了其失效时间后,在第二个程序 coupon-expired 中配置监听器,去监听 reids 失效 key 的通知,在其中配置或监听 redis 的通知操作步骤为两步:

图片1.png

1.定义一个消息的监听器

在 listener 包下创建一个 RedisMessageListener 类同时添加 MessageListener 接口,实现后在 onMessage 方法中去处理消息。

图片2.png

package cn.itcast.redis.listener;

import org.springframework.data.redis.connection.Message;

public class RedisHessageListener implements MessageListener {

//因为需要运用到数据库,注入数据库相关,在此使用 mybits,hmerinate 和 jdbc 都行

@Autowired

private CouponMapper couponMapper;

//处理消息

/**

*完整的处理逻辑如下:

*此时获取的为失效 key 通知

*发送的消息为:key(coupon: 优惠券 id)

* 因此需要的步骤有:

*1.接收到消息获取消息(同时因为获取消息有许多,还需要验证是否是优惠券失效的key)

*2.验证通过后,再从消息中分离出优惠券id

*3.查询数据库获取优惠券对象

*4.设置失效状态,更新数据库

*

*/

public void onMessage(Message message,byte[] pattern){ //通过传入的 message 的 getBody() 方法得到 key,同时还需要强转为 String 类型,因为 getBody() 函数返回值是一个 byte[]数组

String key = new String (message.getBody());

//判断是否是对优惠券的处理,通过if来判断,判断条件为 coupon,因为所有的优惠券都是用 coupon 进行验证的

if(key.startswith( "coupon")) {

//是 coupon 表示对优惠券的处理,之后分离出优惠券 id,在此使用冒号:来拆分数组得到第二个元素 id

String id = key.split(": ")[1];

//得到 id 之后开始查询数据库来获取优惠券对象,在此调用 couponMapper 中的 selectCouponById 方法,同时传入一个 long 类型的参数,而这采用 Long.parseLong(id) 进行了强制转换为 long 类型

Coupon coupon = couponMapper. selectCouponById(Long.parseLong(id));

//设置它的状态,0-有效,1-失效,2-已使用,所以在此设置状态为1已失效

coupon.setState(1);

//同时将 coupon 对象传入,借助 couponMapper 更新

couponMapper.updateCoupon(coupon);

}

}

}

到此全部的处理过程就已经全部结束。

2.将监听类配置到 Spring 配置文件中去

而配置了一个监听类后还需要将其配置到 Spirng 配置文件中去。

图片3.png 

首先打开 resources 中的 applicationContext.xml 配置文件,即其主配置文件,其中定义了数据库操作相关内容,同时其中还引入了 applicationContext-data-redis.xml 配置文件,打开后可以看到其中定义了 redisTemplate、connectionFactory 和 poolConfig 等等,以及消息监听,而消息监听中的<constructor-arg></constructor-arg>注入的就是自定义的监听类。

  • 代码如下:

<! --配置监听-->

<bean class="org.springframework.data.redis.listener.adapter.NessageListenerAdapter" id="messagelListener">

<constructor-arg>

<bean class="cn.itcast.redis.listener.RedisMessggeListener"/>

</constructor-arg>

</bean>

但在监听容器中的<constructor-arg>的value值不能和之前测试类一样写为随意的 ITCAST,而必须改为__keyevent@0__:expired。

  • 代码如下:

<!--监听器容器-->

<bean class="org.springframework.data.redis.Listener.RedisMessageListenerContainer" id="redisContainer">

<!--

*由于需要和 redis 进行交互,注入连接工厂

1.订阅的消息主题

2.接收到消息之后处理的监听器

-->

<property name="connectionFactory" ref="connectionFactory">

</property>

<property name="messageListeners">

<map>

<entry key-ref="messageListener">

<! -- topic 的集合:订阅的主题

订阅了一个主题消息:主题的名称(ITCAST)

接收到一条消息之后,交由自定义的消息监听器来进行处理-->

<list>

<bean class="org. springframework.data.redis.listener.ChannelTopic>

<constructor-arg value="__keyevent@0__:expired"></constructor-arg>

</bean>

</list>

</entry>

</map>

</property>

</bean>

</beans>

3.编写测试

完成了监听和配置到 Spring 配置中后,编写程序让 spring 容器去加载消息监听器让其一直不断的监听 redis 服务器通知。测试的代码核心主要为重写一个 main 方法,再在其中使用 ApplicationContext。

  • 测试类 RedisTest2 的代码如下:

package cn.itcast.redis;

import org.springframework.context.ApplicationContext;

public class RedisTest2{

public static void main(String[]args) {

ApplicationContext ac = new ClassPathxmlApplicationContext("applicationContext.xml");

}

}

Run AS 等待运行成功后,再次运行 CouponTest 就能够获取新的优惠券,当一分钟的失效时间过后,查看是否将优惠券的状态置为失效。可以看到优惠券上又添加了一条新的数据,状态为0。

图片4.png

在 redis 服务器中输入命令行:keys *也可以查看到 coupon:10这条 id 为10优惠券的新记录出现,输入 ttl coupon:10查看该优惠券的失效时间,等待失效时间过去后关闭服务器,可以看到在控制台显示发送了一条数据,同时伴随这许多的 sql 语句,再次查看数据库后,点击刷新,会发现,状态由0变为1,说明当前借助 redis 消息通知成功的将优惠券的状态变为了失效状态。

相关文章
|
NoSQL 算法 Redis
【Docker】(3)学习Docker中 镜像与容器数据卷、映射关系!手把手带你安装 MySql主从同步 和 Redis三主三从集群!并且进行主从切换与扩容操作,还有分析 哈希分区 等知识点!
Union文件系统(UnionFS)是一种**分层、轻量级并且高性能的文件系统**,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem) Union 文件系统是 Docker 镜像的基础。 镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
1153 6
|
缓存 NoSQL Java
Redis应用—6.热key探测设计与实践
热key问题在高并发系统中可能导致数据层和服务层的严重瓶颈,如Redis集群瘫痪和用户体验下降。为解决此问题,京东开发了JdHotkey热key探测框架,具备实时性、准确性、集群一致性和高性能等特点。该框架由etcd集群、Client端jar包、Worker端集群和Dashboard控制台组成,通过分布式计算快速识别热key并推送至应用内存,有效减轻数据层负载,提升服务性能。JdHotkey适用于多种场景,安装部署简便,支持毫秒级热key探测和集群一致性维护。
1128 61
Redis应用—6.热key探测设计与实践
|
NoSQL 测试技术 Redis
Redis批量删除Key的三种方式
Redis批量删除Key是优化数据库性能的重要操作,本文介绍三种高效方法:1) 使用通配符匹配(KEYS/SCAN+DEL),适合不同数据规模;2) Lua脚本实现原子化删除,适用于需要事务保障的场景;3) 管道批量处理提升效率。根据实际需求选择合适方案,注意操作不可逆,建议先备份数据,避免内存溢出或阻塞。
|
消息中间件 缓存 NoSQL
Redis 高并发竞争 key ,如何解决这个难点?
本文主要探讨 Redis 在高并发场景下的并发竞争 Key 问题,以及较为常用的两种解决方案(分布式锁+时间戳、利用消息队列)。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
Redis 高并发竞争 key ,如何解决这个难点?
|
NoSQL API Redis
在C程序中实现类似Redis的SCAN机制的LevelDB大规模key分批扫描
通过上述步骤,可以在C程序中实现类似Redis的SCAN机制的LevelDB大规模key分批扫描。利用LevelDB的迭代器,可以高效地遍历和处理数据库中的大量键值对。该实现方法不仅简单易懂,还具有良好的性能和扩展性,希望能为您的开发工作提供实用的指导和帮助。
428 7
|
NoSQL 数据可视化 Linux
redis学习四、可视化操作工具链接 centos redis,付费Redis Desktop Manager和免费Another Redis DeskTop Manager下载、安装
本文介绍了Redis的两个可视化管理工具:付费的Redis Desktop Manager和免费的Another Redis DeskTop Manager,包括它们的下载、安装和使用方法,以及在使用Another Redis DeskTop Manager连接Redis时可能遇到的问题和解决方案。
2275 1
redis学习四、可视化操作工具链接 centos redis,付费Redis Desktop Manager和免费Another Redis DeskTop Manager下载、安装
|
存储 监控 NoSQL
Redis大Key问题如何排查?如何解决?
Redis大Key问题如何排查?如何解决?
1035 0
Redis大Key问题如何排查?如何解决?
|
存储 NoSQL 算法
面试官:Redis 大 key 多 key,你要怎么拆分?
本文介绍了在Redis中处理大key和多key的几种策略,包括将大value拆分成多个key-value对、对包含大量元素的数据结构进行分桶处理、通过Hash结构减少key数量,以及如何合理拆分大Bitmap或布隆过滤器以提高效率和减少内存占用。这些方法有助于优化Redis性能,特别是在数据量庞大的场景下。
面试官:Redis 大 key 多 key,你要怎么拆分?
|
NoSQL Linux Redis
Docker学习二(Centos):Docker安装并运行redis(成功运行)
这篇文章介绍了在CentOS系统上使用Docker安装并运行Redis数据库的详细步骤,包括拉取Redis镜像、创建挂载目录、下载配置文件、修改配置以及使用Docker命令运行Redis容器,并检查运行状态和使用Navicat连接Redis。
1971 3