Vercel/Netlify Serverless函数生命周期:响应后执行与缓存留存问题
Serverless函数缓存相关问题解答(针对Vercel & Netlify)
背景说明
我有一个用于从GitHub API获取数据并缓存到文件系统的Serverless函数,代码如下:
export async function cachedFetch(url: string, options: RequestInit, cacheKey: string){ let file = Path.join(tmpPath,cacheKey+".cache"); function obtainAndCache(){ return fetch(url, options).then(async r=>{ let text = await r.text(); writeFile(file,text).catch(console.error); // note: don't await the file write return text; }) } if (existsSync(file)){ let stat = await lstat(file); let timeOfLastFetch = stat.mtime.valueOf(); let time = Date.now(); let timeSinceLastFetch = time - timeOfLastFetch; if (timeSinceLastFetch >= MINUTE){ obtainAndCache().catch(console.error); // note: don't await the request } let text = String(await readFile(file)); return text; } else { return obtainAndCache(); } }
预期执行流程:
- 缓存无资源:检查缓存→获取数据→获取完成→启动文件写入→返回资源→文件写入完成
- 缓存有资源:检查缓存→启动新数据请求→返回缓存资源→响应客户端→新请求完成→启动文件写入→文件写入完成
两种场景下,向客户端发送响应后仍有后台代码在运行,因此需要明确以下两个问题:
问题1:发送响应后,代码是否会继续执行?
Vercel
- 函数返回响应后,Vercel会给后台异步任务提供一个短暂的执行窗口(时长不固定,通常几秒到几十秒),但不保证任务一定能执行完成。如果函数实例被系统回收(比如热启动实例因闲置被销毁),未完成的后台任务会被直接终止。
- 你代码中未await的
writeFile和obtainAndCache调用都属于这类后台任务,简单的文件写入大概率能完成,但耗时操作可能中途被打断。
Netlify
- Netlify的Serverless函数(包括Edge Functions)在响应发送后,会保留进程一小段时间处理后台任务,但同样不提供执行完成的保证。
- 轻量的文件写入操作多数情况下能顺利完成,但如果实例被快速回收(比如低流量时段),后台任务会被终止。
问题2:热启动的函数调用之间,tmp目录的文件是否会被保留?
Vercel
- 热启动时,Vercel Serverless函数的
/tmp目录内容会被保留,同一实例的多次调用共享该目录,直到实例被销毁(冷启动时会完全清空目录)。 - 实例存活时间不固定,取决于流量、资源占用等因素,范围从几分钟到几小时不等。
Netlify
- 传统Node.js Serverless函数热启动时,
/tmp目录的内容会被保留,同一实例的后续调用可以访问之前写入的文件。 - Edge Functions的
tmp目录行为类似,热启动时同样会保留目录内容,仅冷启动时清空。
内容的提问来源于stack exchange,提问作者kess
相关产品推荐
相关产品推荐

