当前位置: 首页 > news >正文

37.关注推送

关注的用户有新的评论时,要推送给其他关注他的用户。

关注推送也叫做Feed流,投喂。

通过无线下拉刷新获取新的信息。

1.拉模式,读的压力比较大。每个粉丝都要去读取用户的发件箱中的数据,每次耗时较长。

2.推模式,写的压力比较大。要写给每个粉丝的收件箱里。粉丝读取自己的收件箱很容易。

3.推拉结合模式

对于普通粉丝,采用拉的方式,通过读取用户的收件箱,读的压力就比较大。

对于活跃粉丝,采用推的方式,大V一更新数据就直接写到活跃粉丝的收件箱里。活跃粉丝只需要读取自己收件箱中数据即可。

需求:

1.新增探店笔记时候,保存blog数据到数据库中,然后再将blog的id推送消息到粉丝收件箱。后续就可以根据id在数据库中获取到所有信息。

2.收件箱可以根据时间排序,使用redis的数据结构实现。

3.实现分页效果。

使用的redis的数据结构

list 有序的,有角标也可以实现分页。

sortedset 支持按照评分score排序,排名从0开始可以实现分页获取数据。

按照角标来查的命令:

zrevrange key start end 倒序排名

range key start end 正序排名

range key start end withscores 带上分数

当添加数据后,读取第二页的数据就会出现重复读取了6号位置的数据。

应该采用滚动分页

记录当前页的最后一条数据的位置,下一页查询就从该位置开始查询。

list结构不支持滚动分页查询,它是根据角标去查询的。

所以数据会经常更新变化,就是用滚动查询,那么就需要用到sortedset 结构,可以根据score排序,然后从score的最小值开始滚动查询。

按照分数来查的redis命令

zrevrangebyscore z1 1000 0 withscores limit 0 3

max:分数的最大值,第一次给一个特别大的值,比score的最大值大即可。第二次为第一次查询的score的最小值。如果是时间戳就是当前时间戳肯定是最大值。 

min:分数最小值,默认固定为0。

offset:偏移量,第一次的偏移量固定为0,表示从第一个元素开始。第二次的偏移量=第一次socre的最小值在第一页查询集合中出现的次数。

count:查询的数量,每页的条数

注意:当socre值一样的时候,第二页查询的偏移量不能是1了,而应该是上一页中socre的最小值的个数。比如上一页的score的最小值为6,score在第一页查询集合中有两个,那么偏移量就为2。

 @Overridepublic Long saveBlog(Blog blog) {//获取登录用户UserDTO user = UserHolder.getUser();blog.setUserId(user.getId());boolean save = save(blog);if (!save) {throw new ServiceException("新增探店笔记失败");}//查询笔记作者(当前用户)的所有粉丝List<Follow> follows = followService.query().eq("follow_user_id", user.getId()).list();//推送笔记id给所有粉丝follows.stream().forEach(follow -> {String key = UserConstant.FEED_KEY + follow.getUserId();stringRedisTemplate.opsForZSet().add(key, blog.getId().toString(), System.currentTimeMillis());});//返回idreturn blog.getId();}
 @GetMapping("/of/follow")public ApiResponse blogOfFollow(@RequestParam("lastId") Long lastId,@RequestParam(value = "offset", defaultValue = "0") Integer offset) {//offset 偏移量//lastId 表示每一次查询都要带上上一次查询的时间戳ScrollResult scrollResult = blogService.blogOfFollow(lastId, offset);return ApiResponse.success(scrollResult);}@Overridepublic ScrollResult blogOfFollow(Long lastId, Integer offset) {//1.获取当前用户UserDTO user = UserHolder.getUser();//2.查询收件箱 zrevrangebyscore key max min limit offset countString key = UserConstant.FEED_KEY + user.getId();Set<ZSetOperations.TypedTuple<String>> typedTuples = stringRedisTemplate.opsForZSet().reverseRangeByScoreWithScores(key, 0, lastId, offset, 2);if(typedTuples == null || typedTuples.isEmpty()) {return new ScrollResult();}//3.解析数据:blogId、minTime(时间戳)、offset//初始化好大小,提升性能List<Long> ids = new ArrayList<>(typedTuples.size());Long minTime = 0L;int os = 1;for (ZSetOperations.TypedTuple<String> typedTuple : typedTuples) {String blogId = typedTuple.getValue();ids.add(Long.valueOf(blogId));long time = typedTuple.getScore().longValue();//分数-最小时间戳if(minTime == time) {os++;}else {minTime = time;os = 1;}}//4.根据id查询blogString blogIdsStr = StrUtil.join(",", ids);List<Blog> blogs = query().in("id", ids).last("order by field (id," + blogIdsStr + ")").list().stream().collect(Collectors.toList());blogs.forEach(this::queryBlogUser);//5.封装并返回ScrollResult scrollResult = new ScrollResult();scrollResult.setList(blogs);scrollResult.setMinTime(minTime);scrollResult.setOffset(os);return scrollResult;}
http://www.dtcms.com/a/589325.html

相关文章:

  • iis网站重定向设置微信公众号页面设计模板
  • Go的GRPC框架:Kitex
  • 从Webpack迁移到Rspack
  • 导购分享网站模板了解宿迁建设网站
  • 基于springboot+vue的物流管理系统的设计与实现(源码+论文+部署+安装)
  • (* IOB=“true“ *)
  • 脚本复习--高精度空转(Xenium、CosMx)的细胞邻域分析(R版本)
  • 单链表队列
  • 阀门公司网站建设iis网站配置教程
  • 基于PSO-BP神经网络的MMC子模块开路故障诊断与容错控制研究(含详细代码及仿真分析)
  • Visual Studio 2022 手动搭建 PC 端 lvgl 的调试环境
  • QT-窗口-内置对话框(下)
  • 网站制造设计企业网店推广策略
  • 人工智能备考小结篇(后续会更新对应的题解)
  • 网站系统模板怎么样在网上卖东西
  • 关于网站建设项目的投诉函网站导航栏固定
  • 用Echarts实现“庖丁解牛”的效果
  • 12.线程同步和生产消费模型
  • 消费级MCU如何管理内存
  • zabbix监控ES集群健康状态并触发钉钉告警
  • 一个网站需要几个人建设厅网站技术负责人要求
  • 2025知识协作工具选型,confluence vs 语雀 vs sward哪一款更好用?
  • 【C++】IO多路复用(select、poll、epoll)
  • 高低温环境下DC-DC芯片启动行为对比研究
  • IntelliJIdea 工具新手操作技巧
  • 第3节 STM32 串口通信
  • 网站页面优化内容包括哪些科技信息网站建设的背景
  • 网站做的关键词被屏蔽百度云盘做网站空间
  • 打砖块——反弹算法与碰撞检测
  • 大连网站设计报价建设网站的策划书