在新开发的博客系统中,引入了大量redis,文章/文章列表/分类/标签/评论等等都先从MySQL读取,之后都是从Redis读取。而文章访问量应该怎么设计呢?,每刷新一次+1,数据库异步+1吗?还是使用cookie记录访问了哪些文章,再次刷新不重复计数?
目前采用的是可重复计数,就是页面每刷新一次,访问量+1。每次+1都是在 Redis 中加,到每天某个时刻,同步到MySQL数据库中。
1.在启动类上加 @EnableScheduling 注解
2.创建任务类
可以写多个方法,每个都需要加 @Scheduled 注解,指定相应时间就行。
下面给出一些常用的时间格式
"0 0 12 * * ?" 每天中午十二点触发
"0 15 10 ? * *" 每天早上10:15触发
"0 15 10 * * ?" 每天早上10:15触发
"0 15 10 * * ? *" 每天早上10:15触发
"0 15 10 * * ? 2005" 2005年的每天早上10:15触发
"0 * 14 * * ?" 每天从下午2点开始到2点59分每分钟一次触发
"0 0/5 14 * * ?" 每天从下午2点开始到2:55分结束每5分钟一次触发
"0 0/5 14,18 * * ?" 每天的下午2点至2:55和6点至6点55分两个时间段内每5分钟一次触发
"0 0-5 14 * * ?" 每天14:00至14:05每分钟一次触发
"0 10,44 14 ? 3 WED" 三月的每周三的14:10和14:44触发
"0 15 10 ? * MON-FRI" 每个周一、周二、周三、周四、周五的10:15触发
文章表里一个 post_views 字段,即文章访问量。
当查看文章详情的时候,查询一下该文章的访问量,通常是从缓存中拿,如果没有,从文章对象的postViews属性中拿。
目前采用的是可重复计数,就是页面每刷新一次,访问量+1。每次+1都是在 Redis 中加,到每天某个时刻,同步到MySQL数据库中。
一、SpringBoot 定时任务使用
1.在启动类上加 @EnableScheduling 注解
2.创建任务类
- package com.liuyanzhao.sens.config;
- import com.liuyanzhao.sens.mapper.PostMapper;
- import com.liuyanzhao.sens.model.dto.PostViewsDto;
- import com.liuyanzhao.sens.utils.RedisUtil;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.scheduling.annotation.Scheduled;
- import org.springframework.stereotype.Component;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Set;
- /**
- * @author 言曌
- * @date 2018/12/24 下午4:55
- */
- @Component
- @Slf4j
- public class ScheduledTasks {
- @Autowired
- private RedisUtil redisUtil;
- @Autowired(required = false)
- private PostMapper postMapper;
- /**
- * 同步文章访问量
- */
- @Scheduled(cron = "0 30 4 ? * * ") //每天凌晨4:30执行
- public void syncPostViews() {
- log.info("======================开始 同步文章访问量======================");
- Long startTime = System.nanoTime();
- List<PostViewsDto> dtoList = new ArrayList<>();
- //从redis取值封装List
- Integer prefixLength = "posts_views::posts_views_id_".length();
- Set<String> keySet = redisUtil.keys("posts_views::posts_views_id_*");
- for (String key : keySet) {
- dtoList.add(new PostViewsDto(Long.parseLong(key.substring(prefixLength)), Long.parseLong(redisUtil.get(key))));
- }
- //更新到数据库中
- postMapper.batchUpdatePostViews(dtoList);
- Long endTime = System.nanoTime();
- log.info("本次文章访问量同步成功, 总耗时: {}", (endTime - startTime) / 1000000 + "ms");
- log.info("======================结束 文章访问量结束======================");
- }
- }
可以写多个方法,每个都需要加 @Scheduled 注解,指定相应时间就行。
下面给出一些常用的时间格式
"0 0 12 * * ?" 每天中午十二点触发
"0 15 10 ? * *" 每天早上10:15触发
"0 15 10 * * ?" 每天早上10:15触发
"0 15 10 * * ? *" 每天早上10:15触发
"0 15 10 * * ? 2005" 2005年的每天早上10:15触发
"0 * 14 * * ?" 每天从下午2点开始到2点59分每分钟一次触发
"0 0/5 14 * * ?" 每天从下午2点开始到2:55分结束每5分钟一次触发
"0 0/5 14,18 * * ?" 每天的下午2点至2:55和6点至6点55分两个时间段内每5分钟一次触发
"0 0-5 14 * * ?" 每天14:00至14:05每分钟一次触发
"0 10,44 14 ? 3 WED" 三月的每周三的14:10和14:44触发
"0 15 10 ? * MON-FRI" 每个周一、周二、周三、周四、周五的10:15触发
二、文章访问量的设计
文章表里一个 post_views 字段,即文章访问量。
当查看文章详情的时候,查询一下该文章的访问量,通常是从缓存中拿,如果没有,从文章对象的postViews属性中拿。
- /**
- * 修改文章阅读量
- * Redis增加,定时器同步
- *
- * @param postId 文章Id
- */
- @Override
- public Long updatePostView(Long postId) {
- Long view = this.getPostViewsByPostId(postId);
- if (view == null) {
- return null;
- }
- return redisUtil.incr("posts_views::posts_views_id_" + postId, 1);
- }
- /**
- * 获得某篇文章的访问量
- *
- * @return Long
- */
- @Override
- public Long getPostViewsByPostId(Long postId) {
- String str = redisUtil.get("posts_views::posts_views_id_" + postId);
- if (str == null) {
- Post post = this.findByPostId(postId);
- if (post == null) {
- return null;
- }
- redisUtil.set("posts_views::posts_views_id_" + postId, String.valueOf(post.getPostViews()));
- return post.getPostViews();
- }
- return Long.parseLong(str);
- }
您可以选择一种方式赞助本站
支付宝扫一扫赞助
微信钱包扫描赞助
赏