JooLun Plus 百科 ⬇ 源码下载

04.13 Redis Key 过期提醒

JooLun 于 2026-10-21 14:40:14 +08:00 修改了此页面

原理分析

  • redis的key过期推送功能打开后(自行百度redis的key过期推送怎么打开),程序通过监听器(RedisKeyExpirationListener.java)监听到每个key过期的事件,再做相应处理

涉及到的功能

  • 待支付订单自动取消
  • 订单自动收货
  • 分销佣金自动解冻

举例说明

  • 比如订单自动取消功能,其他功能同理
  1. 生成新订单时,将该订单相关信息存入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);//设置过期时间
  1. 当此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);
				}
			}
			......
		}
	}
  1. 注意:当在key值到期的时间点,刚好redis重启或商城服务重启,系统没有成功监听到redis的消息,此订单自动取消就会失效,需用户手动操作

功能测试

  1. 比如我们在开发测试订单自动取消时,想及时触发过期提醒,不想等30分钟
  2. 我们可以用工具连接redis,找到该订单修改过期时间
  3. 然后在上面的监听器(RedisKeyExpirationListener.java)里debug