如何在Vercel部署的Express应用中周期性执行函数?
问题原因分析
Vercel的Serverless/Edge Functions采用按需启动、闲置休眠的运行模式:只有当有外部请求触发时,函数才会启动执行;一旦一段时间(通常15-30分钟)无请求,就会进入休眠状态,终止所有后台定时任务。另外你原代码用的是setTimeout,本身就只会执行一次,而非循环触发。
解决方案
1. 替换定时逻辑为setInterval
把单次执行的setTimeout改成循环触发的setInterval,保证服务活跃时能持续执行fetchData:
// 立即执行一次 fetchData(); // 之后每10秒执行一次 setInterval(fetchData, 10000);
2. 阻止Vercel服务休眠
要让定时任务持续运行,必须保持服务处于活跃状态,避免进入休眠。可以通过定时向部署域名发送请求实现:
- 编写一个简单的Node.js脚本(可本地运行或部署到其他免费平台),每隔几秒向你的Vercel应用域名发起请求:
const fetch = require('node-fetch'); async function keepAlive() { try { await fetch('https://your-vercel-app-domain.vercel.app'); console.log('服务已保持活跃'); } catch (error) { console.error('保活请求失败:', error); } } // 每9秒发送一次请求(比你的定时任务间隔稍短,确保服务不休眠) setInterval(keepAlive, 9000);
- 运行这个脚本,就能持续触发Vercel应用的服务实例,避免休眠。
3. 调整Vercel部署的代码结构
Vercel部署时不需要手动调用app.listen,它会自动托管你的Express应用。建议把本地启动代码加上环境判断,避免部署时冗余执行:
const PORT = process.env.PORT || 3000; // ...你的其他Express配置代码 fetchData(); setInterval(fetchData, 10000); // 仅在本地开发环境启动监听 if (process.env.NODE_ENV !== 'production') { app.listen(PORT, (err) => { if (err) console.log(err); console.log("Server listening on PORT", PORT); }); } module.exports = app;
注意事项
- Vercel的Serverless Functions有单次执行时长限制(免费计划最长10秒,Pro计划最长60秒),确保你的
fetchData函数执行时间不超过这个限制,否则会被强制终止。 - 如果你的
fetchData是耗时操作,建议拆分逻辑,或者使用Vercel的Edge Functions(启动更快,边缘节点部署)来优化执行效率。
内容的提问来源于stack exchange,提问作者Marcel Dz
相关产品推荐
相关产品推荐

