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]。…...
论文阅读_扩散模型_DM
英文名称: Deep Unsupervised Learning using Nonequilibrium Thermodynamics 中文名称: 使用非平衡热力学原理的深度无监督学习 论文地址: http://arxiv.org/abs/1503.03585 代码地址: https://github.com/Sohl-Dickstein/Diffusion-Probabilistic-Models 时间: 2015-11-18 作…...
【每日运维】RockyLinux8.6升级OpenSSH9.4p1
为什么需要升级openssh呢,因为很多项目进行漏扫结果都会涉及到这个服务器核心组件,一想到以前升级openssh带来的各种依赖性问题就头疼,不管是什么发行版,升级这个东西真的很烦,这次发现可能还会有好一点的通用一点的升…...
libdrm全解析三十八 —— 源码全解析(35)
接前一篇文章:libdrm全解析三十七 —— 源码全解析(34) 本文参考以下博文: DRM 驱动程序开发(VKMS) 特此致谢! 前一篇文章讲解完了drmModeSetCrtc(crtc_id, fb_id, connector_id, mode)&#…...
jar包和war包的区别
SpringBoot项目既可以打成war包发布,也可以找成jar包发布。 jar包 jar包:直接通过内置Tomcat运行,不需要额外安装Tomcat。如需修改内置Tomcat的配置,只需要在SpringBoot的配置文件中配置。内置Tomcat没有自己的日志输出࿰…...
CloudCompare 二次开发(10)——点云投影到平面
目录 一、概述二、代码集成三、结果展示一、概述 不依赖任何第三方点云相关库,使用CloudCompare编程实现点云投影到指定平面,具体计算原理见:PCL 点云投影到拟合平面 二、代码集成 1、mainwindow.h文件public中添加: void doActionProjectToPlane(); // 投影到平面2、…...
如何制作并运行 jar 程序
以下是用 Intellij 制作 jar 程序,并运行的方法。 【1】新建工程,保持默认选项,Next 【2】保持默认选项,Next 【3】给工程命名,设置保存位置,Finish 【4】新建工程结束,进入开发界面 【5】展开…...
Hadoop MapReduce 调优参数
文章目录 MapReduce 调优参数详解MapReduce 调优参数一键复制 前言: 下列参数基于 hadoop v3.1.3 版本,共三台服务器,配置都为 4 核,4G 内存。 MapReduce 调优参数详解 这个参数定义了在 Reduce 阶段同时进行的拷贝操作的数量&…...
springboot 与 Redis整合
SpringBoot 操作数据:Spring-data jpa jdbc mongodb redis! SpringData 也是和SpringBoot 齐名的项目! 说明:在SpringBoot2.X 之后,原来使用的jedis被替换成了lettuce jedis: 采用的直连,多个线程操作的话&…...
如何高效地设计测试用例并评审
编写出好的测试用例是每一个测试工程师的职责,但在实际工作中大家写的测试用例往往需要不断地修改才能使用,这不仅浪费了时间,还容易让测试工程师产生自我否定的情绪,甚至在团队中产生各种矛盾。 那如何高效地设计测试用例呢&…...
基于python+Django知识图谱的医疗问答系统设计与实现
摘 要 从信息技术的发展至今,各色各样的技术能够满足各类人群的需求,能够让各种业务行业的痛点变成能够可以解决的方法,随着我们经济的不断提高,越来越多的人都该关注健康,那么健康饮食、健康医疗是我们生活中所追求的…...
江苏省建设招标网站/快速推广
中国可称为“世界工厂”,但在制造业高歌猛进的同时,没有核心技术、大而不强等问题还是会不断出现。随着工业4.0概念的渐进,中国也在不断通过转型升级来提升制造业整体水平。未来基于互联网技术的产品创新、精益制造、柔性生产以及供应链集成&…...
wordpress指定文章p=/谷歌账号注册
1.优先使用异步消息。 上文已经说过,使用异步消息 Consumer 端需要实现幂等。幂等有两种方式,一种方式是业务逻辑保证幂等。比如接到支付成功的消息订单状态变成支付完成,如果当前状态是支付完成,则再收到一个支付成功的消息则说明…...
网页的制作教案/手机seo快速排名
本文我们就来探索一下 Docker 的神秘世界,从零到一掌握 Docker 的基本原理与实践操作。别再守着前端那一亩三分地,是时候该开疆扩土了。 讲个故事 为了更好的理解 Docker 是什么,我们先来讲个故事: 我需要盖一个房子,于…...
企业网站源码java/百度竞价排名价格
MVPDagger2RxjavaRetrofit 快速实现框架 一个依赖解决所有问题 安卓 Ble 低功耗蓝牙快速开发框架 H-ble 几行代码快速进行 BLE 通信 Dagger2 入门实践 Dagger2 入门实践 急速开发系列——RxJava 实战技巧大全 这几天一直看《激荡三十年》,感觉非常不错。这篇文章本身…...
wordpress 响应式企业主题/如何做推广
转载自:http://blog.csdn.net/hello9050/article/details/7889658链接:http://www.oschina.net/project/tag/264/segment 开源中国社区 1、IKAnalyzer IKAnalyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包。从2006年12月推…...
深圳好看的网站建设哪家公司好/排名优化工具下载
这里以hibernate4.1.7为例,为hibernate-core.jar添加在myEclipse中直接打开查看功能: 说明:我使用的是myEclipse8.5,不通过版本,从视图到方法,可能都存在差异但是道理和组织形式应该是相同的。 现象&#x…...