React.js服务端每日23:59定时执行函数失败求助(Heroku部署)
问题修复:每日定时重置MongoDB字段的服务端脚本
问题根源分析
你的代码存在几个关键问题导致功能失效:
- 每次触发检查时都重新创建MongoDB连接,易引发连接泄漏,且异步操作未妥善处理
- 未考虑时区差异,Heroku服务器默认使用UTC时区,若你预期的是本地时区,23:59的判断会出现偏差
- 无错误日志输出,出现问题无法定位具体原因
- 递归
setTimeout长期运行可能出现时间偏差,且Heroku免费实例会休眠,导致定时任务中断
修复步骤
- 复用MongoDB连接:初始化时建立一次连接,后续操作复用该连接,避免资源浪费
- 处理时区:明确指定时区(比如转为UTC时间判断,或使用时区处理库)
- 添加日志与错误捕获:记录任务执行状态和错误信息,方便排查问题
- 改用可靠定时库:使用
node-schedule替代轮询,更精准控制定时任务 - 适配Heroku环境:若使用免费版,需通过外部工具唤醒休眠实例,或升级到专业版避免休眠
完整修复代码示例
import express from "express"; import cors from "cors"; import bodyParser from "body-parser"; import { MongoClient } from "mongodb"; import schedule from "node-schedule"; const PORT = process.env.PORT || 3001; const app = express(); let dbClient; // 复用MongoDB连接 // 初始化Express中间件 app.use(cors()); app.use(bodyParser.urlencoded({ extended: true })); // 建立MongoDB连接 async function connectDB() { try { dbClient = await MongoClient.connect( "mongodb+srv://<user>:<password>@cluster0.pdunp.mongodb.net/<database>?retryWrites=true&w=majority" ); console.log("MongoDB连接成功"); } catch (err) { console.error("MongoDB连接失败:", err); process.exit(1); // 连接失败退出进程,触发Heroku重启 } } // 定义重置字段的函数 async function resetPercentbuysell() { if (!dbClient) { console.error("MongoDB未连接,无法执行重置操作"); return; } try { const dbo = dbClient.db("player"); const result = await dbo.collection("calcio").updateMany( {}, { $set: { percentbuysell: { buy: 0, sell: 0 } } } ); console.log(`成功重置${result.modifiedCount}条文档的percentbuysell字段`); } catch (err) { console.error("重置操作失败:", err); } } // 启动服务并初始化定时任务 async function startServer() { await connectDB(); // 每天23:59 UTC执行(若需本地时区请调整规则,例如北京时间23:59对应UTC 15:59,规则改为 '59 15 * * *') const job = schedule.scheduleJob("59 23 * * *", () => { console.log("开始执行每日重置任务..."); resetPercentbuysell(); }); app.listen(PORT, () => { console.log(`服务运行在端口${PORT}`); console.log("定时任务已配置:每日23:59 UTC重置字段"); }); } startServer();
额外注意事项
- 安装依赖:执行
npm install node-schedule添加定时库 - Heroku时区调整:根据你的目标时区修改
scheduleJob的时间规则 - 休眠问题处理:免费版实例30分钟无请求会休眠,可使用外部定时服务(如UptimeRobot)每分钟发送请求唤醒,或升级到Heroku专业版
- 日志排查:通过
heroku logs --tail命令查看服务日志,确认任务执行情况
内容的提问来源于stack exchange,提问作者jacopo minelli
相关产品推荐
相关产品推荐

