一、使用背景

很多业务场景,例如订单过期自动删除,订单几天后自动好评,这些常用操作可以通过定时任务,数据库轮询做,但是订单量大的情况可能会对数据库产生大的压力。

二、Redis的key过期推送功能原理分析

Redis的key过期推送功能打开后,程序通过监听器(RedisKeyExpirationListener.java)监听到每个key过期的事件,再做相应处理。

三、打开Redis的key过期推送的正确方式

3.1 为什么要打开?

事件通过 Redis 的订阅与发布功能(pub/sub)来进行分发,故需要开启 redis 的事件监听与发布。

3.2 如何打开?

可以改 redis.conf 文件 打开 notify-keyspace-events Ex 的注释,开启过期通知功能

比如,可以使用 config set notify-keyspace-events Exe 命令来打开 Redis 的 key 过期推送通知。
其中,Ex 表示所有事件都通知,e 表示只通知 key 过期事件。
执行该命令后,可以使用订阅类型的命令(如 PSUBSCRIBE)订阅通知。

四、功能实战1 :待支付订单自动取消功能

步骤1:将该订单相关信息存入Redis

生成新订单时,将该订单相关信息存入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);

步骤2:编写监听器判断订单到期逻辑

当此key值的订单到期时,redis通知到监听器(RedisKeyExpirationListener.java),监听器再判断处理该订单是否需要取消

    @Overridepublic 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);}}......}}

五、功能实战2 : 订单自动收货

步骤1:定义常量

 /*** 订单自动收货时间(天)*/long ORDER_TIME_OUT_2 = 7;

步骤2:编写业务逻辑


@Slf4j
@Service
@AllArgsConstructor
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderInfoService {private final OrderItemService orderItemService;private final OrderLogisticsService orderLogisticsService;private final RedisTemplate<String, String> redisTemplate;private final MallConfigProperties mallConfigProperties;@Override@Transactional(rollbackFor = Exception.class)public boolean updateById(OrderInfo entity) {if (StrUtil.isNotBlank(entity.getLogistics()) && StrUtil.isNotBlank(entity.getLogisticsNo())) {// 发货。更新快递单号entity.setDeliveryTime(LocalDateTime.now());OrderLogistics orderLogistics = orderLogisticsService.getOne(Wrappers.<OrderLogistics>lambdaQuery().eq(OrderLogistics::getId, entity.getLogisticsId()));// 第一次发货调起收到倒计时boolean sendRedis = false;if (StrUtil.isBlank(orderLogistics.getLogistics()) && StrUtil.isBlank(orderLogistics.getLogisticsNo())) {sendRedis = true;}orderLogistics.setLogistics(entity.getLogistics());orderLogistics.setLogisticsNo(entity.getLogisticsNo());orderLogistics.setStatus(OrderLogisticsEnum.STATUS_1.getValue());mallConfigProperties.getLogistics().forEach(logistics -> {if (StrUtil.equals(logistics.getCode(), entity.getLogistics())) {orderLogistics.setLogisticsDesc(logistics.getName());}});orderLogisticsService.updateById(orderLogistics);if (sendRedis) {// 加入redis,7天后自动确认收货String keyRedis = String.valueOf(StrUtil.format("{}{}:{}", MallConstants.REDIS_ORDER_KEY_STATUS_2,TenantContextHolder.getTenantId(), entity.getId()));redisTemplate.opsForValue().set(keyRedis, entity.getOrderNo(), MallConstants.ORDER_TIME_OUT_2,TimeUnit.DAYS);// 设置过期时间}}return super.updateById(entity);}

【项目实战】Redis使用场景之待支付订单自动取消、订单自动收货相关推荐

  1. php redis zset 延迟队列_用PHP+Redis实现延迟任务,实现自动取消订单

    简单定时任务解决方案:使用redis的keyspace notifications(键失效后通知事件) 需要注意此功能是在redis 2.8版本以后推出的,因此你服务器上的reids最少要是2.8版本 ...

  2. php 超时支付取消订单,php利用workerman的定时器实现延时操作(订单支付不成功后一定时间未支付自动取消订单)...

    延时操作个人目前接触最多的场景是用户下单后一定时间未支付自动取消订单,传统的做法是采用定时任务定时扫描数据库超时订单或者利用客户端的请求每次请求去检测一次是否有超时订单,这些方法我始终感觉不是很好,所 ...

  3. tp5.1 PHP + Redis实现自动取消订单

    PHP + Redis实现自动取消订单 业务场景 Redis 开启 keyspace notifications tp5.1 代码实现 后台运行脚本   简单定时任务解决方案:使用redis的keys ...

  4. 使用PHP+Redis实现延迟任务,实现自动取消订单功能

    简单定时任务解决方案:使用redis的keyspace notifications(键失效后通知事件) 需要注意此功能是在redis 2.8版本以后推出的,因此你服务器上的reids最少要是2.8版本 ...

  5. PHP+Redis实现延迟任务 实现自动取消订单,自动完成订单

    简单定时任务解决方案:使用redis的keyspace notifications(键失效后通知事件) 需要注意此功能是在redis 2.8版本以后推出的,因此你服务器上的reids最少要是2.8版本 ...

  6. B2C电商项目(第十三天、超时未支付订单处理、订单批量发货、确认收货与自动收货)

    订单处理 课程内容: 通过 rabbitmq的延迟消息完成超时订单处理 完成批量发货功能,了解第三方物流系统 完成自动收货功能 一.超时未支付订单处理 1.1 需求分析 超过限定时间并未支付的订单,我 ...

  7. 商品下单未支付,如何取消订单?

    一.业务场景 当下完订单,一般超过15分钟或者30分钟就需要对未支付的订单进行关闭. 二.解决方案 1.定时任务 通过定时任务隔一段时间扫描一次的数据,超过时间的订单,修改为取消状态 public c ...

  8. rabbitMQ实现订单超时未支付自动取消订单

    前期准备 下面展示一些 内联代码片. 1.配置文件,导入jar包 server:port: 8983 spring:application:name: API-RABBITMQdatasource:t ...

  9. 深度学习项目实战——基于多模态场景监控系统

    摘要 项目背景:这是分布式智能环卫系统项目,主要是针对小区物业.环卫公司和政府监管部门以及居民用户等使用的系统.为了小区物业更加智能化,环卫的托运效率提高,社区的管理高效,方便政府和街道部门的监控.而 ...

最新文章

  1. 苹果官方 Crash文件分析方法 (iOS系统Crash文件分析方法)
  2. Sth about Haml
  3. 用border-width,border-color画三角形
  4. Linux命令之 mount -- 文件系统挂载
  5. 游戏王血计算机,【统计】历代主角控血一览
  6. ajax deletemapping,springmvc使用put,delete方法传参问题,以及使用@PutMapping注解和@DeleteMapping注解...
  7. Ubuntu14.04安装build-essential失败,包依赖问题如何解决?
  8. 机器学习—XGboost的原理、工程实现与优缺点
  9. 帮您管好云:阿里云混合云管理平台发布 | 凌云时刻
  10. 计算机专业 论文检索,精选】计算机专业文献检索论文参考选题
  11. Linux ubuntu14.04 下 chromium 浏览器 CPU占用资源优化
  12. 基于微信小程序的国产动漫论坛小程序
  13. python怎么解压rar文件_用Python解压缩rar、zip文件的方法
  14. 三点钟社群联合发起人Sky: 中国版“马克·扎克伯格”,用区块链激励差异化价值创造者...
  15. 博通Broadcom SDK源码学习与开发11——Cable Modem DHCP管理
  16. linux发广告软件下载,ADPower广告管理系统(Linux手动安装)
  17. 【人工智能哲学01/2】人工智能前世今生
  18. 2021-2025年中国口服降糖药和胰岛素类似物行业市场供需与战略研究报告
  19. 真空喷射式排气装置(真空脱气机)原理介绍
  20. 拼多多信誉度太低,怎么办?

热门文章

  1. IoT黑板报:中国移动基站将支持无线充电
  2. 总结 : 2019CCPC女生专场
  3. 物联网课程学习目标_恒华科技(300365)泛在电力物联网建设加速,助力实现全年高增长目标...
  4. 程序化的思维与一通百通,一切语言都是纸老虎
  5. 【使用篇】WebView 实现嵌套滑动,丝滑般实现吸顶效果,完美兼容 X5 webview
  6. ATOS插装阀ATOS插装阀
  7. html input文本框样式,css 定义input文本输入框样式
  8. 计算机的配置与选购调查报告,目前主流危机计算机的配置及选购的调查报告
  9. Mars3d widget 学习记录(二)index.html
  10. python怎么清屏_python怎么清屏