来自 Heroku 官方帮助中心:https://devcenter.heroku.com/articles/request-timeout
超时值不可配置。如果您的服务器需要超过 30 秒才能完成给定请求,我们建议将该工作移至后台任务或工作线程以定期 ping 您的服务器以查看处理请求是否已完成。此模式可以释放您的 Web 进程来执行更多工作,并减少总体应用程序响应时间。
简短的回答是:不,您无法更改此配置。我建议您调查一下为什么您的应用程序需要 30 秒以上的时间来处理该请求。如果花费的时间超过 10 秒,您确实应该考虑 Heroku 帮助中心建议的步骤????
你的问题
您提到您需要这个来进行文件处理。据我了解,文件处理时间很可能会超过 30 秒。通常我要做的就是创建某种任务引用并将其与状态(“处理”,“完成”,“失败”)一起保存在数据库中 - 还存储原始文件,然后结束请求用户。这应该不会花很长时间。然后处理任务...使用另一个端点或 websocket 连接,用户可以检查任务是否已完成。
使用任务队列
以下只是解决方案的基本解释 - 它不适用于复制和粘贴,因为它取决于很多事情。
路线(终点)
基本上你的后端需要有 3 条路由。一份用于上传文件,一份用于下载已处理的文件,一份用于检查任务的状态。
1. 上传
app.post('/files', /* some middleware e.g. multer */, async (req, res) => {
// This is your upload controller
// I assume at this point the file has been uploaded and
// req.file contains a reference to the uploaded file.
// create new process task and add to queue
const task = await createNewTask(req.file);
queue.push(task);
// now a task has been created, but the user
// doesn't need to wait for it to finish
// so let's end the request here.
return req.status(200).json(task);
});
2. 检查状态
app.get('/task/:id', async (req, res) => {
// From uploading a file in the first step, you'll
// get back a task id. Use the task id to check on
// the status.
const task = await getTask(req.params.id);
if (!task) {
return res.status(404).end();
} else {
return res.status(200).json(task);
}
});
该任务可以包括状态、进度百分比、原始文件名、新文件名等信息,甚至是完成后处理的文件的下载链接。状态可能是这样的pending
, processing
, finished
or failed
.
3. 下载
app.get('/file/:filename', (req, res) => {
return req.status(200)
.sendFile('./path/to/file/' + req.params.filename);
});
Notes