一、简介
本次文章主要实现功能是接入redis作为定时器,倒计时实现订单超时未处理时,超时提醒。
本次讲解中代码是在已经接入redis作为缓存的前提下进一步开发,具体可参考 SpringBoot配置redis作为缓存(含源码)
使用步骤分别是①调用下单接口,存入redis数据 ② 调用订单处理接口,手动处理redis数据,手动处理后不再会有超时提醒 ③未处理的订单会自动监听超时提醒
二、使用前提
在windows中启动redis和redis桌面管理工具,分享连接在文章最下方
三、实现效果
三、代码实现步骤
1.添加redis配置类
package com.cpl.tsl.config; 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.RedisMessageListenerContainer; /** * Redis配置类 * * @author: lll * @date: 2022年03月07日 13:03:27 */ @Configuration public class RedisTaskConfig { @Bean RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(connectionFactory); return container; } }
2.添加redis监听
package com.cpl.tsl.listener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.connection.Message; import org.springframework.data.redis.listener.KeyExpirationEventMessageListener; import org.springframework.data.redis.listener.RedisMessageListenerContainer; import org.springframework.stereotype.Component; import java.util.Date; /** * RedisKey键监听以及业务逻辑处理 * * @author: lll * @date: 2022年03月07日 14:03:49 */ @Component public class RedisTaskListener extends KeyExpirationEventMessageListener { private static final Logger logger = LoggerFactory.getLogger(RedisTaskListener.class); @Value("${applicationName:tsl}") private String applicationName; /** * @param listenerContainer 监听器 */ public RedisTaskListener(RedisMessageListenerContainer listenerContainer) { super(listenerContainer); } @Override public void onMessage(Message message, byte[] pattern) { String expiredKey = message.toString(); // 将拿到的过期键使用之前拼接时的特殊符号分割成字符数组 String[] expiredKeyArr = expiredKey.split("\\|"); String businessSign = expiredKeyArr[0].toString(); String expiredTimeSign = expiredKeyArr[1].toString(); logger.info(businessSign +":"+ expiredTimeSign); Date date = new Date(); // 只有本业务才执行以下操作 if (businessSign.equals(applicationName + ":ORDERINFO")) { logger.info("订单超时,已取消"); } else { logger.error("非订单业务不做处理"); } } }
3.添加controller调动接口
package com.cpl.tsl.controller; import com.cpl.tsl.utils.RedisUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import java.util.Date; import java.util.UUID; /** * 测试类 * * @author: lll * @date: 2021年06月02日 18:06:58 */ @RestController @RequestMapping("/") @Api(tags = "测试模块") public class TestController { private static final Logger logger = LoggerFactory.getLogger(TestController.class); @Resource private RedisTemplate<String, String> template; @Resource private RedisUtil redisUtil; @Value("${applicationName:tsl}") private String applicationName; /** * redis设置定时key,模拟订单下单,超时提醒或者去掉订单 * * @param * @return java.lang.String * @author: lll * @date: 2022年03月07日 13:03:59 */ @RequestMapping(value = "/putkeys", method = RequestMethod.POST) @ApiOperation(value = "测试redis存储参数", notes = "测试redis存储参数") public String putRedisTaskKeys() { /** * 存入订单信息 */ Date date = new Date(); //设置超时时间30秒 Long overTime = new Long(30); //创建订单号 String orderNo = UUID.randomUUID().toString(); //订单信息 String orderInfo = "这是订单号为:" + orderNo + " 的订单,价格是:2000元,下单时间是:" + date; //redis key String redisKey = applicationName + ":ORDERINFO|" + orderNo; redisUtil.set(redisKey, orderInfo, overTime); logger.info("下单时间:" + date); logger.info("订单的redisKey " + redisKey + " 订单信息 " + orderInfo); return "下单成功"; } /** * 手动处理订单,从redis移除订单 * * @param orderNo 订单号 * @return java.lang.String * @author: lll * @date: 2022年03月07日 14:03:58 */ @RequestMapping(value = "/removeKeys", method = RequestMethod.POST) @ApiOperation(value = "测试redis移除参数", notes = "测试redis移除参数") public String removeRedisTaskKeys(@ApiParam(name = "orderNo", value = "订单号", required = true) @RequestParam("orderNo") String orderNo) { /** * 处理订单 */ //拼接redis key String redisKey = applicationName + ":ORDERINFO|" + orderNo; //删除redis key redisUtil.del(redisKey); logger.info("订单redisKey " + redisKey + " 已处理"); return "处理完成"; } }
四、资源
源码:https://github.com/CodingPandaLLL/tsl.git
源码压缩包地址:https://codeload.github.com/CodingPandaLLL/tsl/zip/refs/tags/1.0.4