您现在的位置是:网站首页> 编程资料编程资料
Redis实战之百度首页新闻热榜的实现代码_Redis_
2023-05-27
367人已围观
简介 Redis实战之百度首页新闻热榜的实现代码_Redis_
目标
利用Redis实现类似百度首页新闻热榜功能。
功能
新闻排行榜以热度为指标降序排序,这里假设热度就是评论数量且统计的热度时间范围以当天为准;根据新闻的时效性,这里假设每15分钟刷新一次新闻榜单。
分析 Zset数据类型:一个有序集合最多 个元素,集合元素有序不可重复,每个元素都会关联一个double类型的分数。元素根据分数从小到大的排序,分数可以重复。zscore命令可以对分数实现增量,且如果该Zset中没有该元素,则会创建该条数据。可以将模块名+当天的时间作为Zset的键,用户评论量作为分数,新闻标题作为值,每当用户评论一次新闻,分数则相应地加1。每隔15分钟提取新闻统计中的前30名(包含第30名)榜单,放入到新闻热榜的Zset中。
代码实现
控制层
package com.shoppingcart.controller; import com.shoppingcart.service.NewsTopServer; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import java.util.List; import java.util.Map; /** * 新闻排行榜 */ @RestController @RequestMapping("/newsTop") public class NewsTopController { @Resource public NewsTopServer newsTopServer; /** * http://localhost:8099/newsTop/zscoreNews?newTitle=《欢乐喜剧人7》全新赛制养成新人&score=434000 * 创建新闻统计&实时统计新闻热度 * @param newTitle 新闻标题 (根据业务也可以写成新闻ID) * @param score 热度增量 * @return 给新闻一个增量以后,返回新闻的当前分数。 */ @GetMapping("/zscoreNews") public MapzscoreNews( @RequestParam(value = "newTitle", required = true) String newTitle, @RequestParam(value = "score", defaultValue = "1") double score ) { Map map = newsTopServer.incrementScore(newTitle, score); return map; } /** * http://localhost:8099/newsTop/findNewByNewTitle?newTitle=《欢乐喜剧人7》全新赛制养成新人 * 查询某条新闻的热度 * @param newTitle * @return */ @GetMapping("/findNewByNewTitle") public Map findNewByNewTitle( @RequestParam(value = "newTitle", required = true) String newTitle ) { Map map = newsTopServer.findNewByNewTitle(newTitle); return map; } /** * http://localhost:8099/newsTop/createNewsTop?startPage=0&endPage=29 * 对统计的新闻数据降序排序,并将[29,0]之间的数据放入新闻排行榜。(这个方法可以设置成定时任务。) * @param startPage 开始下标 * @param endPage 结束下标 * @return */ @GetMapping("/createNewsTop") public Map createNewsTop( @RequestParam(value = "startPage", defaultValue = "0") int startPage, @RequestParam(value = "endPage", defaultValue = "29") int endPage ) { Map map = newsTopServer.createNewsTop(startPage, endPage); return map; } /** * http://localhost:8099/newsTop/newsTop?startPage=20&endPage=29 * 对统计的新闻数据降序排序,并将[29,0]之间的数据放入新闻排行榜。(这个方法可以设置成定时任务。) * * @param startPage 开始下标 * @param endPage 结束下标 * @return */ @GetMapping("/newsTop") public Map newsTop( @RequestParam(value = "startPage", defaultValue = "0") int startPage, @RequestParam(value = "endPage", defaultValue = "9") int endPage ) { Map map = newsTopServer.newsTop(startPage, endPage); return map; } /** * http://localhost:8099/newsTop/addTestData * 批量增加测试数据(新闻统计) */ @PostMapping("/addTestData") public void addTestData(@RequestBody List
业务层
package com.shoppingcart.service; import java.util.Map; public interface NewsTopServer { MapincrementScore(String newTitle,double zscore); Map findNewByNewTitle(String newTitle); Map createNewsTop(int startPage, int endPage); Map newsTop(int startPage, int endPage); }
package com.shoppingcart.service.impl; import com.shoppingcart.service.NewsTopServer; import com.shoppingcart.utils.RedisService; import org.springframework.data.redis.core.ZSetOperations; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.*; @Service public class NewsTopServerImpl implements NewsTopServer { @Resource private RedisService redisService; @Override public MapincrementScore(String newTitle, double score) { Map map = new HashMap<>(); //String key= "newsSta:"+DateUtils.dateToString(new Date(),"yyyyMMdd"); String key = "newsSta:" + "20210123"; Double d = redisService.incrementScore(key, newTitle, score); Map m = new HashMap () { { put("key", key); put("newTitle", newTitle); put("score", d); } }; map.put("data", m); map.put("code", 0); return map; } @Override public Map findNewByNewTitle(String newTitle) { //String key= "newsSta:"+DateUtils.dateToString(new Date(),"yyyyMMdd"); String key = "newsSta:" + "20210123"; Double d = redisService.score(key, newTitle); Map map = new HashMap<>(); Map m = new HashMap () { { put("key", key); put("newTitle", newTitle); put("score", d); } }; map.put("data", m); map.put("code", 0); return map; } /** * @param startPage * @param endPage * @return */ @Override public Map createNewsTop(int startPage, int endPage) { Map map = new HashMap<>(); //新闻统计键 //String newsStaKey= "newsSta:"+DateUtils.dateToString(new Date(),"yyyyMMdd"); String newsStaKey = "newsSta:" + "20210123"; //新闻前30排名键 //String newsTopKey= "newsSta:"+DateUtils.dateToString(new Date(),"yyyyMMdd"); String newsTopKey = "newsTop:" + "20210123"; //查询前30的信息(Interface Comparable :该接口对实现它的每个类的对象强加一个整体排序。) Set > set = redisService.reverseRangeWithScores(newsStaKey, startPage, endPage); if (set == null || set.size() == 0) { map.put("data", null); map.put("code", 1); return map; } //删除旧的新闻排行榜 redisService.del(newsTopKey); //添加新闻排行榜数据 Long zsetSize = redisService.zsetAdd(newsTopKey, set); Map m = new HashMap () { { put("data", set); put("size", zsetSize); } }; map.put("data", m); map.put("code", 0); return map; } /** * 查看新闻热榜(TOP30) * * @param startPage * @param endPage * @return */ @Override public Map newsTop(int startPage, int endPage) { //新闻统计键 //String newsStaKey= "newsSta:"+DateUtils.dateToString(new Date(),"yyyyMMdd"); String newsStaKey = "newsSta:" + "20210123"; //新闻前30排名键 //String newsTopKey= "newsSta:"+DateUtils.dateToString(new Date(),"yyyyMMdd"); String newsTopKey = "newsTop:" + "20210123"; Set > set = redisService.reverseRangeWithScores(newsTopKey, startPage, endPage); Map m = new HashMap (); m.put("data", set); m.put("size", set.size()); //新闻排行榜为空,也许现在正在添加数据,先查询新闻统计键。 if (set == null || set.size() == 0) { //查询前30的信息(Interface Comparable :该接口对实现它的每个类的对象强加一个整体排序。) Set > set2 = redisService.reverseRangeWithScores(newsStaKey, startPage, endPage); m.put("data", set); m.put("size", set.size()); } Map map = new HashMap<>(); map.put("data", m); map.put("code", 0); return map; } }
工具类
package com.shoppingcart.utils; import java.text.SimpleDateFormat; import java.util.Date; public class DateUtils { // 日期转字符串,返回指定的格式 public static String dateToString(Date date, String dateFormat) { SimpleDateFormat sdf = new SimpleDateFormat(dateFormat); return sdf.format(date); } }
package com.shoppingcart.utils; import com.alibaba.fastjson.JSONObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.connection.RedisZSetCommands; import org.springframework.data.redis.connection.SortParameters; import org.springframework.data.redis.core.DefaultTypedTuple; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ZSetOperations; import org.springframework.stereotype.Service; import org.spring
相关内容
- Redis实战之商城购物车功能的实现代码_Redis_
- 利用redis实现分布式锁,快速解决高并发时的线程安全问题_Redis_
- Redis和数据库 数据同步问题的解决_Redis_
- Redis 实现同步锁案例_Redis_
- 同一份数据Redis为什么要存两次_Redis_
- Redis实现分布式Session管理的机制详解_Redis_
- kubernetes环境部署单节点redis数据库的方法_Redis_
- 银河麒麟V10sp1服务器系统安装redis不能使用的快速解决办法_Redis_
- Redis6.0搭建集群Redis-cluster的方法_Redis_
- 浅谈Redis存储数据类型及存取值方法_Redis_
点击排行
本栏推荐
