04.13 Redis Key 过期提醒
JooLun 于 2026-10-21 14:40:14 +08:00 修改了此页面
原理分析
- redis的key过期推送功能打开后(自行百度redis的key过期推送怎么打开),程序通过监听器(RedisKeyExpirationListener.java)监听到每个key过期的事件,再做相应处理
涉及到的功能
- 待支付订单自动取消
- 订单自动收货
- 分销佣金自动解冻
举例说明
- 生成新订单时,将该订单相关信息存入redis,并设置过期时间
//加入redis,30分钟自动取消
String keyRedis = String.valueOf(StrUtil.format("{}{}:{}",MallConstants.REDIS_ORDER_KEY_IS_PAY_0,TenantContextHolder.getTenantId(),orderInfo.getId()));
redisTemplate.opsForValue().set(keyRedis, orderInfo.getOrderNo() , orderTimeOut , TimeUnit.MINUTES);//设置过期时间
- 当此key值的订单到期时,redis通知到监听器(RedisKeyExpirationListener.java),监听器再判断处理该订单是否需要取消
@Override
public void onMessage(Message message, byte[] bytes) {
RedisSerializer<?> serializer = redisTemplate.getValueSerializer();
String channel = String.valueOf(serializer.deserialize(message.getChannel()));
String body = String.valueOf(serializer.deserialize(message.getBody()));
//key过期监听
if(StrUtil.format("__keyevent@{}__:expired", redisConfigProperties.getDatabase()).equals(channel)){
//订单自动取消
if(body.contains(MallConstants.REDIS_ORDER_KEY_IS_PAY_0)) {
body = body.replace(MallConstants.REDIS_ORDER_KEY_IS_PAY_0, "");
String[] str = body.split(":");
String wxOrderId = str[1];
TenantContextHolder.setTenantId(str[0]);
OrderInfo orderInfo = orderInfoService.getById(wxOrderId);
if(orderInfo != null && CommonConstants.NO.equals(orderInfo.getIsPay())){//只有待支付的订单能取消
orderInfoService.orderCancel(orderInfo);
}
}
......
}
}
- 注意:当在key值到期的时间点,刚好redis重启或商城服务重启,系统没有成功监听到redis的消息,此订单自动取消就会失效,需用户手动操作
功能测试
- 比如我们在开发测试订单自动取消时,想及时触发过期提醒,不想等30分钟
- 我们可以用工具连接redis,找到该订单修改过期时间

- 然后在上面的监听器(RedisKeyExpirationListener.java)里debug