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

10.Quartz实现定时打分 热帖排行

1.Spring Quartz

(1)简介

核心组件

  1. scheduler 接口:核心调度工具,所有任务由这一接口调用

  1. job:定义任务,重写execute方法

  1. JobDetail接口:配置描述

  1. Trigger接口:什么时候运行,以什么样的频率运行

(2)Spring 整合

  • 引入依赖

  • 将配置表导入数据库

  1. qrtz_job_details:job详情配置描述表

  1. qrtz_simple_triggers:触发器相关配置简述

  1. qrtz_jtriggers:触发器相关完整配置

  1. qrtz_scheduler:定时器状态

  1. qrtz_locks:定时器锁

  • QuartzPropertie

spring.quartz.job-store-type=jdbc
spring.quartz.scheduler-name=communityScheduler 
spring.quartz.properties.org.quartz.scheduler.instanceId=AUTO 
#spring.quartz.properties.org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
spring.quartz.properties.org.quartz.jobStore.class=org.springframework.scheduling.quartz.LocalDataSourceJobStore
spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate 
spring.quartz.properties.org.quartz.jobStore.isClustered=true 
spring.quartz.properties.org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool 
spring.quartz.properties.org.quartz.threadPool.threadCount=5 

BUG:从spring5.3.6使用org.quartz.impl.jdbcjobstore.JobStoreTX定义quartz的默认数据源支持,如下

org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
  • 实现我们自己的job,重写execute方法

  • 在QuartzConfig里

  • 配置 JobDetail

// 配置JobDetail
@Bean
public JobDetailFactoryBean alphaJobDetail() {JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();factoryBean.setJobClass(AlphaJob.class);factoryBean.setName("alphaJob");factoryBean.setGroup("alphaJobGroup");factoryBean.setDurability(true);factoryBean.setRequestsRecovery(true);return factoryBean;
}
实例化JobDetailFactoryBean
声明管理的管理的是谁.setJobClass
声明job任务的名字.setName
声明任务属于的组.setGroup
声明任务是否长久保存.setDurability
声明任务是否可恢复.setRequestsRecovery
  • 配置Trigger

// 配置Trigger(SimpleTriggerFactoryBean, CronTriggerFactoryBean)
@Bean
public SimpleTriggerFactoryBean alphaTrigger(JobDetail alphaJobDetail) {SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean();factoryBean.setJobDetail(alphaJobDetail);factoryBean.setName("alphaTrigger");factoryBean.setGroup("alphaTriggerGroup");factoryBean.setRepeatInterval(3000);factoryBean.setJobDataMap(new JobDataMap());return factoryBean;
}
实例化SimpleTriggerFactoryBean
声明管理的管理的是谁.setJobClass
声明job任务的名字.setName
声明任务属于的组.setGroup
声明任务执行的频率.setRepeatInterval
声明Trigger的存储状态类型.setJobDataMap

  1. 热帖排行

用一个set将分数变化的帖子的id装起来,定时从中取出 更新

(1)统计发生分数变化的帖子

点赞 评论 精华 发布时间会影响分数

  • RedisKeyUtil

  • 添加方法统计帖子分数

// 帖子分数
public static String getPostScoreKey() {return PREFIX_POST + SPLIT + "score";
}
  • DiscussPostController

  • 发布帖子 设置精华 的方法里补充

// 计算帖子分数
String redisKey = RedisKeyUtil.getPostScoreKey();
redisTemplate.opsForSet().add(redisKey, post.getId());
  • CommentController

  • addComment添加评论时做处理

  • LikeController

  • like 点赞时 做处理

(2)写定时任务Job

public class PostScoreRefreshJob implements Job, CommunityConstant {private static final Logger logger = LoggerFactory.getLogger(PostScoreRefreshJob.class);@Autowiredprivate RedisTemplate redisTemplate;@Autowiredprivate DiscussPostService discussPostService;@Autowiredprivate LikeService likeService;@Autowiredprivate ElasticsearchService elasticsearchService;// 牛客纪元private static final Date epoch;static {try {epoch = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2014-08-01 00:00:00");} catch (ParseException e) {throw new RuntimeException("初始化牛客纪元失败!", e);}}@Overridepublic void execute(JobExecutionContext context) throws JobExecutionException {String redisKey = RedisKeyUtil.getPostScoreKey();BoundSetOperations operations = redisTemplate.boundSetOps(redisKey);if (operations.size() == 0) {logger.info("[任务取消] 没有需要刷新的帖子!");return;}logger.info("[任务开始] 正在刷新帖子分数: " + operations.size());while (operations.size() > 0) {this.refresh((Integer) operations.pop());}logger.info("[任务结束] 帖子分数刷新完毕!");}private void refresh(int postId) {DiscussPost post = discussPostService.findDiscussPostById(postId);if (post == null) {logger.error("该帖子不存在: id = " + postId);return;}// 是否精华boolean wonderful = post.getStatus() == 1;// 评论数量int commentCount = post.getCommentCount();// 点赞数量long likeCount = likeService.findEntityLikeCount(ENTITY_TYPE_POST, postId);// 计算权重double w = (wonderful ? 75 : 0) + commentCount * 10 + likeCount * 2;// 分数 = 帖子权重 + 距离天数double score = Math.log10(Math.max(w, 1))+ (post.getCreateTime().getTime() - epoch.getTime()) / (1000 * 3600 * 24);// 更新帖子分数discussPostService.updateScore(postId, score);// 同步搜索数据post.setScore(score);elasticsearchService.saveDiscussPost(post);}}

(3)配置 JobDetails Trigger

@Configuration
public class QuartzConfig {@Beanpublic JobDetailFactoryBean postScoreRefreshJobDetail() {JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();factoryBean.setJobClass(PostScoreRefreshJob.class);factoryBean.setName("postScoreRefreshJob");factoryBean.setGroup("communityJobGroup");factoryBean.setDurability(true);factoryBean.setRequestsRecovery(true);return factoryBean;}@Beanpublic SimpleTriggerFactoryBean postScoreRefreshTrigger(JobDetail postScoreRefreshJobDetail) {SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean();factoryBean.setJobDetail(postScoreRefreshJobDetail);factoryBean.setName("postScoreRefreshTrigger");factoryBean.setGroup("communityTriggerGroup");factoryBean.setRepeatInterval(1000 * 60 * 5);factoryBean.setJobDataMap(new JobDataMap());return factoryBean;}
}
http://www.lryc.cn/news/22563.html

相关文章:

  • pandas 读取Excel 批量转换时间戳
  • 绕过检测之Executor内存马浅析(内存马系列篇五)
  • 《C++模板进阶》
  • 【项目管理】项目进度管理中的逻辑关系
  • ARM的汇编指令集
  • @font-face用法超详细讲解
  • [oeasy]python0095_乔布斯求职_雅达利_atari_breakout_打砖块_布什内尔_游戏机_Jobs
  • 全景极简印度史
  • 《设计模式》模板方法
  • Linux环境内存管理——链表
  • String、StringBuffer、StringBuilder类
  • 在VScode中添加Linux中的Docker容器中的Python解释器
  • 无法将“django-admin”项识别为cmdlet,函数,脚本文件或可运行程序的名称问题
  • 乐友商城学习笔记(十五)
  • 目标检测论文阅读:CBNet算法笔记
  • vue前端与Java后端进行跨域交互
  • 【设计模式】2.抽象工厂模式
  • Telnet 基础实验1: Telnet 实验
  • 机器学习经典算法——决策树(Decision Tree)
  • MySQl总结
  • 【学习笔记】NOIP爆零赛7
  • 一文读懂账号体系产品设计
  • 从“入门”到“专家”,一份3000字完整的性能测试体系的知识分享
  • 构建对话机器人:Rasa3安装和基础入门
  • Spark计算框架入门笔记
  • 入职数据分析公认的好书|建议收藏
  • Linux查找文件和目录,重定向输出 ,系统默认运行级别的查看和设置理论和练习
  • Redis源码---键值对中字符串的实现,用char*还是结构体
  • 算法 - 剑指Offer 表示数值的字符串
  • 初识机器学习