JavaWeb_LeadNews_Day10-Xxljob, Redis实现定时热文章
JavaWeb_LeadNews_Day10-Xxljob, Redis实现定时热文章
- xxl-job概述
- windows部署调度中心
- docker部署调度中心
- xxl-job入门案例
- xxl-job分片广播
- 热点文章定时计算
- 思路分析
- 具体实现
- 热文章计算
- 定时计算
- 查询文章接口改造
- 来源
- Gitee
xxl-job概述
windows部署调度中心
- 运行 xxl-job\doc\db\tables_xxl_job.sql
- 修改 xxl-job-admin子模块下的application.properties
spring.datasource.password=1234
- 启动 xxl-job-admin子模块下的启动程序
- 访问localhost:8080/xxl-job-admin, 账号: admin, 密码:123456
docker部署调度中心
- 创建mysql容器
docker run -p 3306:3306 --name mysql57 \
-v /opt/mysql/conf:/etc/mysql \
-v /opt/mysql/logs:/var/log/mysql \
-v /opt/mysql/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:5.7.25
- 拉取镜像
docker pull xuxueli/xxl-job-admin:2.3.0
- 创建xxl-job-admin容器
docker run -e PARAMS="--spring.datasource.url=jdbc:mysql://192.168.174.133:3306/xxl_job?Unicode=true&characterEncoding=UTF-8 \
--spring.datasource.username=root \
--spring.datasource.password=root" \
-p 8888:8080 -v /tmp:/data/applogs \
--name xxl-job-admin -d xuxueli/xxl-job-admin:2.3.0
xxl-job入门案例
- 调度中心新建示例任务
- 依赖
<dependency><groupId>com.xuxueli</groupId><artifactId>xxl-job-core</artifactId><version>2.3.0</version> </dependency>
- 配置
application.yml
XxlJobConfig.javaserver:port: 8881xxl:job:admin:addresses: http://192.168.174.133:8888/xxl-job-adminexecutor:appname: xxl-job-executor-sampleport: 9999
@Configuration public class XxlJobConfig {private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);@Value("${xxl.job.admin.addresses}")private String adminAddresses;@Value("${xxl.job.executor.appname}")private String appname;@Value("${xxl.job.executor.port}")private int port;@Beanpublic XxlJobSpringExecutor xxlJobExecutor() {logger.info(">>>>>>>>>>> xxl-job config init.");XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();xxlJobSpringExecutor.setAdminAddresses(adminAddresses);xxlJobSpringExecutor.setAppname(appname);xxlJobSpringExecutor.setPort(port);return xxlJobSpringExecutor;}/*** 针对多网卡、容器内部署等情况,可借助 "spring-cloud-commons" 提供的 "InetUtils" 组件灵活定制注册IP;** 1、引入依赖:* <dependency>* <groupId>org.springframework.cloud</groupId>* <artifactId>spring-cloud-commons</artifactId>* <version>${version}</version>* </dependency>** 2、配置文件,或者容器启动变量* spring.cloud.inetutils.preferred-networks: 'xxx.xxx.xxx.'** 3、获取IP* String ip_ = inetUtils.findFirstNonLoopbackHostInfo().getIpAddress();*/ }
- 任务代码
@Component public class HelloJob {@XxlJob("demoJobHandler")public void demoJobHandler(){XxlJobHelper.log("XXL-JOB, Hello World.");System.out.println("简单任务执行...");}}
xxl-job分片广播
- 创建分片执行器
xxl-job-sharding-sample
- 创建任务, 路由策略为分片广播
- 分片广播任务代码, 创建多个实例
@XxlJob("shardingJobHandler") public void shardingJobHandler() {// 分片的参数int shardIndex = XxlJobHelper.getShardIndex(); // 实例在集群中的序号int shardTotal = XxlJobHelper.getShardTotal(); // 集群总量// 业务逻辑List<Integer> list = getList();for (Integer integer : list) {if(integer % shardTotal == shardIndex){System.out.println("当前分片: "+shardIndex+", 当前任务项: "+integer);}} }public List<Integer> getList() {List<Integer> list = new ArrayList<>();for (int i = 0; i < 10000; i++) {list.add(i);}return list; }
热点文章定时计算
思路分析
具体实现
热文章计算
@Slf4j
@Service
@Transactional
public class HotArticleServiceImpl implements HotArticleService {@Autowiredprivate ApArticleMapper apArticleMapper;/*** 计算热门文章*/@Overridepublic void computeHotArticle() {// 1. 查询前5天的文章数据Date dayParam = DateTime.now().minusDays(5).toDate();List<ApArticle> articleList = apArticleMapper.findArticleListByLast5days(dayParam);// 2. 计算文章的分值List<HotArticleVo> hotArticleVoList = getHotArticleVoList(articleList);// 3. 为每个频道缓存30条分值较高的文章cacheTagToRedis(hotArticleVoList);}@Autowiredprivate IWemediaClient wemediaClient;@Autowiredprivate CacheService cacheService;/*** 为每个频道缓存30条分值较高的文章* @param hotArticleVoList*/private void cacheTagToRedis(List<HotArticleVo> hotArticleVoList) {// 为每个频道缓存30条分值较高的文章ResponseResult responseResult = wemediaClient.getChannels();if(responseResult.getCode().equals(200)){String jsonString = JSON.toJSONString(responseResult.getData());List<WmChannel> wmChannelList = JSON.parseArray(jsonString, WmChannel.class);// 检索出每个频道的文章if(wmChannelList!=null){for (WmChannel wmChannel : wmChannelList) {List<HotArticleVo> hotArticleVos = hotArticleVoList.stream().filter(item ->item.getChannelId().equals(wmChannel.getId())).collect(Collectors.toList());// 给文章排序, 取30条分值较高的文章存入redis key: 频道id value: 30条分值较高的文章sortAndCache(hotArticleVos, ArticleConstants.HOT_ARTICLE_FIRST_PAGE + wmChannel.getId());}}}// 设置推荐数据// 给文章排序, 取30条分值较高的文章存入redis key: 频道id value: 30条分值较高的文章sortAndCache(hotArticleVoList, ArticleConstants.HOT_ARTICLE_FIRST_PAGE + ArticleConstants.DEFAULT_TAG);}/*** 排序并且缓存数据* @param hotArticleVos* @param key*/private void sortAndCache(List<HotArticleVo> hotArticleVos, String key) {hotArticleVos = hotArticleVos.stream().sorted(Comparator.comparing(HotArticleVo::getScore).reversed()).collect(Collectors.toList());if(hotArticleVos.size() > 30){hotArticleVos = hotArticleVos.subList(0, 30);}cacheService.set(key, JSON.toJSONString(hotArticleVos));}/*** 获取热文章列表* @param articleList* @return*/private List<HotArticleVo> getHotArticleVoList(List<ApArticle> articleList) {List<HotArticleVo> articleVoList = new ArrayList<>();if(articleList!=null) {for (ApArticle apArticle : articleList) {HotArticleVo hotArticleVo = new HotArticleVo();BeanUtils.copyProperties(apArticle, hotArticleVo);Integer score = computeArticleScore(apArticle);hotArticleVo.setScore(score);articleVoList.add(hotArticleVo);}}return articleVoList;}/*** 计算文章分数* @param apArticle* @return*/private Integer computeArticleScore(ApArticle apArticle) {Integer score = 0;if(apArticle.getLikes() != null){score += ArticleConstants.HOT_ARTICLE_LIKE_WEIGHT*apArticle.getLikes();}if(apArticle.getComment() != null){score += ArticleConstants.HOT_ARTICLE_COMMENT_WEIGHT*apArticle.getComment();}if(apArticle.getCollection() != null){score += ArticleConstants.HOT_ARTICLE_COLLECTION_WEIGHT*apArticle.getCollection();}if(apArticle.getViews() != null){score += apArticle.getViews();}return score;}
}// ApArticleMapper.java
List<ApArticle> findArticleListByLast5days(@Param("dayParam") Date dayParam);// ApArticleMapper.xml
<select id="findArticleListByLast5days" resultType="com.heima.model.article.pojos.ApArticle">SELECTaa.*FROM`ap_article` aaLEFT JOIN ap_article_config aac ON aa.id = aac.article_id<where>and aac.is_delete != 1and aac.is_down != 1<if test="dayParam != null">and aa.publish_time <![CDATA[>=]]> #{dayParam}</if></where>
</select>
总结:
ApArticleMapper.java
中的形参必须添加@Param注解, 否则在ApArticleMapper.xml
中会将dayParam解释为Date的属性然后报错.
定时计算
- 新建热文章计算执行器
leadnews-hot-article-executor
- 新建定时任务
- 依赖和配置
- 任务代码
@Component @Slf4j public class ComputeHotArticleJob {@Autowiredprivate HotArticleService hotArticleService;@XxlJob("computeHotArticleJob")public void handle(){log.info("热文章分值计算调度任务开始执行...");hotArticleService.computeHotArticle();log.info("热文章分值计算调度任务执行结束...");}}
查询文章接口改造
// article-Controller
public class ArticleHomeController {...public ResponseResult load(@RequestBody ArticleHomeDto articleHomeDto){// return apArticleService.load(articleHomeDto, ArticleConstants.LOADTYPE_LOAD_MORE);return apArticleService.load2(articleHomeDto, ArticleConstants.LOADTYPE_LOAD_MORE, true);}...
}// article-Service
public ResponseResult load2(ArticleHomeDto dto, Short type, boolean firstPage) {if(firstPage==true){String jsonString = cacheService.get(ArticleConstants.HOT_ARTICLE_FIRST_PAGE + dto.getTag());if(StringUtils.isNotBlank(jsonString)){List<HotArticleVo> hotArticleVoList = JSON.parseArray(jsonString, HotArticleVo.class);return ResponseResult.okResult(hotArticleVoList);}}return load(dto, type);
}
来源
黑马程序员. 黑马头条
Gitee
https://gitee.com/yu-ba-ba-ba/leadnews
相关文章:

JavaWeb_LeadNews_Day10-Xxljob, Redis实现定时热文章
JavaWeb_LeadNews_Day10-Xxljob, Redis实现定时热文章 xxl-job概述windows部署调度中心docker部署调度中心 xxl-job入门案例xxl-job分片广播热点文章定时计算思路分析具体实现热文章计算定时计算 查询文章接口改造来源Gitee xxl-job概述 windows部署调度中心 运行 xxl-job\do…...
【WebRTC---源码篇】(二:二)视频源VideoSourceBase
作用 这个类继承自VideoSourceInterface<webrtc::VideoFrame>模板类,并且可以处理webrtc::VideoFrame class VideoSourceBase : public VideoSourceInterface<webrtc::VideoFrame> 重要成员变量 struct SinkPair {SinkPair(VideoSinkInterface<webrtc::Vid…...
Linux_8_磁盘存储和文件系统
1 磁盘结构 1.1 设备文件 一切皆文件: open(),read(),write(),close() 设备文件:关联至一个设备驱动程序,进而能够跟与之对应硬件设备进行通信 设备号码: 主设备号 major number,标识设备类型 次设备号 minor number,标识同一类型下的不同设备 设备类型:…...

VS + QT 封装带UI界面的DLL
一、创建编译DLL的项目 1.新建Qt Class Liabrary 2.新建项目,选择Qt Widgets Class 3.新建C类,可以在此类里面写算法函数用于调用。 4.下面是添加完Qt窗体类和C类之后的项目截图 5.修改头文件并编译 将uidemo_global.h中的ifdef内容复制到dialog.h上…...

逆向工程-架构真题(二十)
结构化程序设计采用自顶向下、逐步求精及模块化程序设计方法,通过()三种基本控制结构可以构造出任何单入口单出口程序。 顺序、选择和嵌套顺序、分支和循环分支、并发和循环跳转、选择和并发 答案:B 解析: 结构化设…...

Zookeeper 入门
第 1 章 Zookeeper 入门 1.1概述 Zookeeper从设计模式角度来理解:是一个基于观察者模式设计的分布式服务管理框架,它负责存储和管理大家都关心的数据,然后接受观察者的注册,一旦这些数据的状态发生变化,Zookeeper就将…...

记录--前端使用a链接下载内容增加loading效果
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 问题描述:最近工作中出现一个需求,纯前端下载 Excel 数据,并且有的下载内容很多,这时需要给下载增加一个 loading 效果。 代码如下: // util…...
如何获取用户的ip地址
用户的 IP 地址可能会被隐藏或者修改,例如使用代理服务器、VPN 等工具,这样就无法准确获取用户的真实 IP 地址。 除了以上特殊情况,一般情况下 用户访问可能会经过一下链路 : 前端—>nginx—>网关—>服务 。 一般情况下后…...

单片机-控制按键点亮LED灯
1、按键电路图 定义四个按键引脚 1、按键按下 为 输入为低电平 2、按键不按下 IO有上拉电阻,为高电平 // 定义 按键的 管教 sbit KEY1 P3^1; sbit KEY2 P3^0; sbit KEY3 P3^2; sbit KEY4 P3^3; 2、LED灯电路图 LED 输出高电平为亮 // 定义LED灯 管教 sbit LED1…...

微信小程序新版隐私协议弹窗实现最新版
1. 微信小程序又双叒叕更新了 2023.08.22更新: 以下指南中涉及的 getPrivacySetting、onNeedPrivacyAuthorization、requirePrivacyAuthorize 等接口目前可以正常接入调试。调试说明: 在 2023年9月15号之前,在 app.json 中配置 __usePriva…...
GO语言圣经 第五章习题
练习5.1 修改findlinks代码中遍历n.FirstChild链表的部分,将循环调用visit,改成递归调用。 func visit(links []string, n *html.Node) []string {if n nil {return links}if n.Type html.ElementNode && n.Data "a" {for _, a : r…...
用kotlin 开发一个简单的多页面跳转
本文介绍一个简单的安卓应用的页面跳转例子,用的是kotlin。 运行时主页面是一个hello 和Jump 按钮,你按一下jump 按钮就转到 从页面,只是标识从页面。 开始建立一个简单工程,名为hello, 选择的是Empty views Activit…...
记录我的tensorrt 部署yolov8
系统 :ubuntu 18.04 代码 :GitHub - noahmr/yolov5-tensorrt: Real-time object detection with YOLOv5 and TensorRT conda 环境 : GitHub - noahmr/yolov5-tensorrt: Real-time object detection with YOLOv5 and TensorRT cuda : 11.8 …...
什么是用户界面? 优漫动游
什么是用户界面? 用户界面(UI,UserInterface)也称人机界面,是人机交互、操作逻辑和界面表现的整体设计。每一种设计都有其对应的职业角色,其中,人机交互的设计人员叫做用户研究工程师,操作逻辑设计人员叫…...

基于 Docker 的 MySQL 主从复制搭建(Mac M1版本)
系统:Macbook M1 镜像版本:mysql:5.7 如果是要查 slave连接不上 master的问题,可以直接跳到文章末尾踩坑处 准备工作 拉取镜像 docker pull mysql:5.7本地数据卷挂载 因为mysql不挂载的话,重启丢失数据,所以在本地创…...

【Locomotor运动模块】瞬移
文章目录 一、原理二、两种类型1、Instant(立刻)2、Dash(猛冲) 三、瞬移区域、瞬移点1、瞬移区域2、瞬移点 一、原理 抛物线指针选择好目标位置,然后告诉瞬移预设体:你想法把游戏区域弄到目标位置来 解释:抛物线指针选…...

【负载均衡】常见的负载均衡策略有哪些?
文章目录 前言负载均衡分类常见负载均衡策略小结 前言 负载均衡策略是实现负载均衡器的关键,而负载均衡器又是分布式系统中不可或缺的重要组件。使用它有助于提高系统的整体性能、可用性、可靠性和安全性,同时支持系统的扩展和故障容忍性。对于处理大量…...
ChatGPT如何应对紧急救援和医疗应急?
ChatGPT在紧急救援和医疗应急方面具有潜在的重要用途。它可以用于提供信息、建议和支持,以帮助应对各种突发事件,如自然灾害、流行病爆发、事故等。以下是ChatGPT如何应对紧急救援和医疗应急的方式以及相关挑战的详细讨论。 ### 紧急救援 #### 1. 提供…...

vue3 ref reactive响应式数据 赋值的问题
文章目录 vue3 ref reactive响应式数据 赋值的问题场景1:将响应式数据赋值请求后的数据错误示范:直接赋值正确写法 场景2:响应式数据解构之后失去响应式原因分析解决办法 toRefs/toRef方法创建ref引用对象 vue3 ref reactive响应式数据 赋值的问题 doing…...
【美团秋招】20230922小美的彩虹糖
小美的彩虹糖 小美有很多的彩虹糖,每颗彩虹糖都有一个颜色,她每天可以吃两颗彩虹糖,如果今天吃的彩虹糖组合是之前没吃过的组合,则小美今天会很高兴。 例如,小美有 6 颗彩虹糖,颜色分别是 [1,1,4,5,1,4]。…...

shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...

Reasoning over Uncertain Text by Generative Large Language Models
https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...

免费PDF转图片工具
免费PDF转图片工具 一款简单易用的PDF转图片工具,可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件,也不需要在线上传文件,保护您的隐私。 工具截图 主要特点 🚀 快速转换:本地转换,无需等待上…...
scikit-learn机器学习
# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...
LRU 缓存机制详解与实现(Java版) + 力扣解决
📌 LRU 缓存机制详解与实现(Java版) 一、📖 问题背景 在日常开发中,我们经常会使用 缓存(Cache) 来提升性能。但由于内存有限,缓存不可能无限增长,于是需要策略决定&am…...

R 语言科研绘图第 55 期 --- 网络图-聚类
在发表科研论文的过程中,科研绘图是必不可少的,一张好看的图形会是文章很大的加分项。 为了便于使用,本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中,获取方式: R 语言科研绘图模板 --- sciRplothttps://mp.…...