来自官方 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 或failed。
3。下载
app.get('/file/:filename', (req, res) => {
return req.status(200)
.sendFile('./path/to/file/' + req.params.filename);
});
注意事项