3 步跑通 NewsRecommendSystem:Quartz 定时新闻推荐任务配置指南
【免费下载链接】FactoryBluePrints游戏戴森球计划的**工厂**蓝图仓库项目地址: https://gitcode.com/GitHub_Trending/fa/FactoryBluePrints
每天一睁眼就手动触发一遍推荐计算,这活儿完全可以交给机器。NewsRecommendSystem 是一款开源的定时新闻推荐系统:接入 Quartz 任务调度后,推荐任务会按 Cron 表达式配置的时间自动执行,一次配好,每位用户的推荐结果每天自己刷新。下面按"先跑起来、再看原理、最后调优"的顺序,带你从建库走到日常运维。
🚀 先跑起来:建库、改配置、启动任务
第一步,把五张核心表建好
推荐任务的读写全落在 MySQL 上,一共五张表:
users:用户信息news:新闻内容newsmodules:新闻模块newslogs:浏览记录Recommendations:推荐结果
前四张是输入,最后一张是输出——每次定时执行完,结果就写进Recommendations。
第二步,改两个 properties 文件
配置文件都放在res/目录下,各管一件事。
res/dbconfig.properties管数据库连接,把三项换成你自己的:
url = jdbc:mysql://[数据库IP]/[数据库名]?useUnicode=true&characterEncoding=utf8 user = [用户名] password = [密码]res/paraConfig.properties管任务行为,三个常用项:
startAt=0 0 0 ? * * # 任务触发时间,Cron 表达式 CFRecNum=5 # 每个用户推荐几条 CFValidDay=-30 # 浏览历史算多少天有效第三步,启动最小任务
打开src/top/qianxinyao/Main/Main.java,在 main 方法里加两行,三种算法全开,先给全体用户跑一轮:
boolean enableCF = true, enableCB = true, enableHR = true; new JobSetter(enableCF, enableCB, enableHR).executeQuartzJobForAllUsers();进程跑起来后,到startAt指定的时刻,调度器会自动把任务派出去,结果表里就能看到当天生成的推荐。任务的入口类在src/top/qianxinyao/main/JobSetter.java,下一节拆原理时还会反复提到它。
调度是怎么工作的
Quartz 是 Java 生态里最老牌的任务调度框架之一,可以把它理解成后台闹钟:你登记好任务和触发时间,它到点自动把任务跑起来。
三种用户范围,一次选一种
JobSetter 把"给谁算推荐"抽象成三种模式,对应不同的启动方法:
| 模式 | 覆盖人群 | 入口方法 | 适合什么时候用 |
|---|---|---|---|
| 全体用户 | 所有注册用户 | executeQuartzJobForAllUsers() | 每日全局刷新 |
| 活跃用户 | 近期(如 30 天内)有浏览行为的用户 | executeQuartzJobForActiveUsers() | 算力有限,优先算这批人 |
| 指定用户 | 你自己给定的用户名单 | 由 JobSetter 提供对应入口 | 小范围验证、定向推送 |
新用户多、历史行为少的时候,用活跃用户模式能省掉大量无效计算;做 A/B 测试或活动推送,指定用户模式最省事。
Cron 表达式逐段怎么读
Cron 表达式是一串按固定顺序排列的时间描述,Quartz 按"秒 分 时 日 月 周"六段解析(年段可选,一般不写):
| 段序 | 含义 | 常见写法 |
|---|---|---|
| 1 | 秒 | 0 |
| 2 | 分 | 0–59 |
| 3 | 时 | 0–23 |
| 4 | 日 | ?或具体日期 |
| 5 | 月 | *或 1–12 |
| 6 | 周 | *或 MON、FRI 等 |
两个常用写法:
"0 0 2 ? * *"; // 每天凌晨 2 点整 "0 0 9 ? * MON"; // 每周一上午 9 点整把startAt改成前者,任务就会在每天 2 点触发。?的作用是让"日"和"周"互斥:既然指定了周几,日字段就得让出来。
三种推荐算法各管什么
三个定时任务分别由三个 Runner 类承载,分工很清晰:
| 算法 | 定位 | 定时入口 | 关键参数 / 技术 |
|---|---|---|---|
| CF 协同过滤 | 找行为相似的用户,用他们的偏好补全你的信息流 | src/top/qianxinyao/UserBasedCollaborativeRecommender/quartz/CFCronTriggerRunner.java | CFRecNum=5、CFValidDay=-30 |
| CB 基于内容 | 提取新闻内容特征,匹配用户兴趣偏好 | src/top/qianxinyao/contentbasedrecommend/quartz/CBCronTriggerRunner.java | TF-IDF 关键词提取、相似度计算 |
| HR 热点新闻 | 筛出全站最受欢迎的新闻,保底不冷场 | src/top/qianxinyao/hotrecommend/quartz/HRCronTriggerRunner.java | 热度筛选 |
CF 依赖历史行为,用户越老越准;CB 看内容不看人,没行为的新用户也能覆盖;HR 最粗但最快,是信息流的压舱石。三者在 JobSetter 里由三个布尔开关独立控制,可任意组合:
| 组合 | 适合场景 | 原因 |
|---|---|---|
| CF+CB+HR | 日常全量推荐 | 三路互补,覆盖面最全 |
| CB+HR | 新用户、冷启动 | 不依赖历史行为,靠内容和热度兜底 |
| CF+HR | 社交属性强的平台 | 群体效应明显,热门+相似用户更准 |
调优与排错
把重活留给低峰时段
推荐计算是典型的 CPU 加数据库重负载,三条经验:
- 时间上躲开高峰:让
startAt落在用户离线时段,并排在新闻抓取完成之后,别和白天高峰抢资源。 - 用户量大就分批:把全量用户切批执行,避免一次性把内存和连接打满。
- 热点预计算:热点新闻变化慢,可以先算好放缓存,HR 任务只做校验和增量更新;数据库侧再启用连接池复用连接。
任务失败排查顺序
到点没出结果时,按这个顺序查,命中率最高:
- 调度器日志:先看 Quartz 有没有按时触发任务、任务内部报了什么异常;
- Cron 格式:再核对
startAt的六段是否写对,周字段用了 MON 就确认日字段是?; - 数据库连接:最后确认
res/dbconfig.properties的 IP、账号、密码、库名都能连通。
Quartz 自带任务持久化和错过补偿:进程重启后任务还在,宕机期间错过的触发会按策略补跑;集群部署时,多个节点也能分担负载。
常见问题
Q:任务到点了但没执行,从哪查起?A:先翻 Quartz 调度器日志确认触发情况,再核对 Cron 表达式,最后测数据库连通性,三步走完基本能定位。
Q:想调整某个算法的产出,改哪里?A:改res/paraConfig.properties里对应的参数,比如CFRecNum(每人推荐条数)和CFValidDay(行为有效天数);想要更细的控制,可以自定义推荐结果的融合策略。
Q:能只给一部分用户推送吗?A:能。全体、近期活跃、指定名单三种筛选任选,对应 JobSetter 的不同入口方法。
写在最后
到这里,定时新闻推荐的主链路就通了:五张表、两个配置文件、一个 JobSetter 调用,剩下的都是调参数。建议先把startAt定在每天凌晨,观察一周执行日志,再根据推荐质量回头微调CFRecNum和CFValidDay——自动化只是把重复劳动交出去,推荐做得准不准,还得看你对参数和数据的理解。
【免费下载链接】FactoryBluePrints游戏戴森球计划的**工厂**蓝图仓库项目地址: https://gitcode.com/GitHub_Trending/fa/FactoryBluePrints
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考