SpringBoot 定时任务从Redis同步文章访问量

在新开发的博客系统中,引入了大量redis,文章/文章列表/分类/标签/评论等等都先从MySQL读取,之后都是从Redis读取。而文章访问量应该怎么设计呢?,每刷新一次+1,数据库异步+1吗?还是使用cookie记录访问了哪些文章,再次刷新不重复计数?

目前采用的是可重复计数,就是页面每刷新一次,访问量+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);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值