redis订阅和发布应用场景?

您所在的位置:网站首页 publish与public redis订阅和发布应用场景?

redis订阅和发布应用场景?

2023-04-10 06:33| 来源: 网络整理| 查看: 265

一、需求

C端App上,用户是否能在某个时间段内选择配送,需要在后台实时统计每个时段(每个小时或每半个小时)的订单数,并考虑当前仓内拣货打包和仓外配送的压力请求,决定用户可以选择的配送时段。

二、方案

使用redis的zset (sorted set )数据结构进行实时统计分析。

redis 有序集合zset和集合set一样也是string类型元素的集合,且不允许重复的成员。不同的是 zset 的每个元素都会关联一个分数(分数可以重复),redis 通过分数来为集合中 的成员进行从小到大的排序。

每天每个仓使用一个zset的key存储,orderId作为zset的member,订单对应的预计完成时间戳作为zset的score;

当用户下一个订单时,就记录这个orderId,及订单对应的预计完成时间戳 (zadd)。

当订单取消、或配送完成是,就从这个zset中删除这个订单(zrem)。

查询时间段内的订单数,只需要把时间段的起止时间戳作为zset的score,使用zcount即可统计订单数

三、zset测试127.0.0.1:6379> # 1.添加,如果值存在添加,将会重新排序。zadd 127.0.0.1:6379> zadd user 1 wuxiaolong (integer) 1 127.0.0.1:6379> zadd user 10 sukailiang 8 yufeng 5 shilei 6 huangchao (integer) 4 127.0.0.1:6379> # 2.查看zset集合的成员个数。zcard 127.0.0.1:6379> zcard user (integer) 5 127.0.0.1:6379> # 3.查看Zset指定范围的成员,withscores为输出结果带分数。zrange 127.0.0.1:6379> zrange user 3 8 1) "yufeng" 2) "sukailiang" 127.0.0.1:6379> zrange user 3 8 withscores 1) "yufeng" 2) "8" 3) "sukailiang" 4) "10" 127.0.0.1:6379> zrange user 0 -1 withscores 1) "wuxiaolong" 2) "1" 3) "shilei" 4) "5" 5) "huangchao" 6) "6" 7) "yufeng" 8) "8" 9) "sukailiang" 10) "10" # 4.获取zset成员的下标位置,如果值不存在返回null。zrank 127.0.0.1:6379> zrank user yufeng (integer) 3 127.0.0.1:6379> zrank user wuxiaolong (integer) 0 127.0.0.1:6379> zrank user nobody (nil) 127.0.0.1:6379> # 5.获取zset集合指定分数之间存在的成员个数。zcount 127.0.0.1:6379> zcount user 3 8 (integer) 3 127.0.0.1:6379> zcount user 5 8 (integer) 3 # 6.删除指定的一个成员或多个成员。zrem 127.0.0.1:6379> zrem user yufeng (integer) 1 127.0.0.1:6379> zrem user nobody (integer) 0 127.0.0.1:6379> # 7.获取指定值的分数。zscore 127.0.0.1:6379> zscore user wuxiaolong "1" 127.0.0.1:6379> zscore user nobody (nil) 127.0.0.1:6379> zscore user shilei "5" 127.0.0.1:6379> # 8.给指定元素的分数进行增减操作,负值为减,正值为加。zincrby 127.0.0.1:6379> 127.0.0.1:6379> zincrby user 3 shilei "8" 127.0.0.1:6379> zscore user shilei "8" 127.0.0.1:6379> ​ 127.0.0.1:6379> zrange user 0 -1 withscores 1) "wuxiaolong" 2) "1" 3) "huangchao" 4) "6" 5) "shilei" 6) "8" 7) "sukailiang" 8) "10" 127.0.0.1:6379> 127.0.0.1:6379> # 9.根据指定分数的范围获取值。zrangebysocre 127.0.0.1:6379> zrangebyscore user 0 8 1) "wuxiaolong" 2) "huangchao" 3) "shilei" 127.0.0.1:6379> # 10.倒序,从高到底排序输出指定范围的数据。zrevrange,zrevrangebyscore 127.0.0.1:6379> zrevrange user 0 -1 1) "sukailiang" 2) "shilei" 3) "huangchao" 4) "wuxiaolong" 127.0.0.1:6379> zrevrange user 0 -1 withscores 1) "sukailiang" 2) "10" 3) "shilei" 4) "8" 5) "huangchao" 6) "6" 7) "wuxiaolong" 8) "1" 127.0.0.1:6379> 127.0.0.1:6379> 127.0.0.1:6379> # 11.根据坐标,分数范围删除数据。zremrangebyscore,zremrangebyrank 127.0.0.1:6379> zrevrangebyscore user 8 1 1) "shilei" 2) "huangchao" 3) "wuxiaolong" 127.0.0.1:6379> 127.0.0.1:6379> 127.0.0.1:6379> # 12.zset还有求两个集合的交集和并集的操作。zunionzstore,zinterstore 四、JAVA测试1.controllerpackage message.queue.engine.controller; ​ import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.ZSetOperations; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; ​ import java.util.Calendar; import java.util.Date; import java.util.concurrent.TimeUnit; ​ @RestController @RequestMapping(value = "/v1") public class HelloController { ​ @Autowired private ZSetOperations zSetOperations; ​ @RequestMapping("/add") public Boolean add(@RequestParam("orderId") String orderId){ ​ // 履约时间 Date deliveryDate = new Date(); ​ // 履约日期 String ymd = Utils.getYMD(deliveryDate); ​ // 每天一个key String key = Const.STAT_PREFIX+ ymd; ​ // 放入订单号 重复orderId会覆盖 Boolean result = zSetOperations.add(key, orderId, deliveryDate.getTime()); ​ // 存储一周 if(result){ Boolean expire = zSetOperations.getOperations().expire(key, Const.RDS_EXPIRE_DAY, TimeUnit.DAYS); } ​ return result; } ​ @RequestMapping("/del") public Long del(@RequestParam("orderId") String orderId){ ​ // 履约时间 Date deliveryDate = new Date(); ​ // 履约日期 String ymd = Utils.getYMD(deliveryDate); ​ // 每天一个key String key = Const.STAT_PREFIX+ ymd; ​ // 删除 Long remove = zSetOperations.remove(key, orderId); ​ return remove; } ​ @RequestMapping("/stat") public Long stat(){ ​ // 当前时间 Date now = new Date(); // 时间段长度 以30分钟划分一天的时段 int segmentType = 30; ​ // 履约日期 String ymd = Utils.getYMD(now); ​ // 每天一个key String key = Const.STAT_PREFIX+ ymd; ​ // 今天开始 Calendar calendar = Calendar.getInstance(); calendar.setTime(now); calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); Date todayStart = calendar.getTime(); ​ // 相对时间段 Long relativeTime = now.getTime() - todayStart.getTime(); ​ long[] segmentArr; if(segmentType ==30){ segmentArr = Const.TIME_SEGMENT_30; }else { segmentArr = Const.TIME_SEGMENT_60; } ​ Long start = null; Long end = null; for (int i=0; i= segmentArr[i] && relativeTime


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3