Loading

分时统计表+定时器,解决排行、报表等数据量大的业务场景

一、需求

项目业务在做一个攻略排行,要求每隔一段时间,更新排行榜

二、分析方案

  • redis缓存,先执行一次查询,然后缓存在redis中,下一次查询直接查询redis
    缺点:占用内存,数据不实时,可能会出现缓存策略失效,接着把请求传到 mysql 中,这样请求也会变慢

  • 分时统计表(大表转小表),这个表是专门统计数据的,先执行一次大表查询,然后将数据保存在分时统计表,下一次直接查询分时统计表
    缺点:数据不实时

综上,攻略排行榜对于用户来说,时效性的需求没有那么强烈,抛开实时的缺点,采用大表转小表的方式十分契合我们的需求

三、技术

  • 项目基于 SpringBoot,采用定时器,实现分时统计
  • 统计(小)表设计

四、代码实现

Spring定时器
启动类需要贴注解 @EnableScheduling

@EnableScheduling
@SpringBootApplication
public class MgrApp {

    public static void main(String[] args) {
        SpringApplication.run(MgrApp.class, args);
    }
}

编写定时任务

@Component
public class StrategyRankDataJob {

    @Autowired
    private IStrategyRankService strategyRankService;

    /**
     * 维护攻略排行表
     * 每天早8点更新
     */

    @Scheduled(cron = "0 0 8 * * *")
    public void StrategyRankMaintain(){
        strategyRankService.maintain(StrategyRank.TYPE_HOT);
    }
}

服务实现层

 @Override
    public void maintain(Integer type) {
        if (type != null) {
            QueryWrapper<Strategy> wrapper = new QueryWrapper<>();
            List<StrategyRank> strategyRankList = new ArrayList<>();
            Date maintainTime = new Date();// 放外面,让下面整体更新时间一致
            
            // 热门
            /*  select 列 from strategy order by (viewnum+replynum) desc limit 10*/
            // 显示前 10 条
            wrapper.select(列);
            wrapper.orderByDesc("viewnum+replynum");
            wrapper.last("limit 10");
            List<Strategy> list = strategyService.list(wrapper);
            for (Strategy strategy : list) {
                StrategyRank strategyRank = new StrategyRank();
                strategyRank.setXX(...);
                strategyRankList.add(strategyRank);
            }
            super.saveBatch(strategyRankList);
        }
    }

以上,完成需求

posted @ 2021-08-17 21:40  JereCode  阅读(301)  评论(0编辑  收藏  举报