如何在heroku中有超过30秒的响应超时



Guys Heroku终止请求,如果响应需要超过30秒返回,所以有什么办法我可以等待,只要响应会回来吗?

用户正在上传他的文件,我需要在我的服务器上对文件做一些事情,更新完成后,我会给用户一个下载链接。但大多数情况下,服务器处理文件的时间超过30秒,因此用户需要等待响应

来自官方Heroku帮助中心:https://devcenter.heroku.com/articles/request-timeout

超时值不可配置。如果您的服务器需要超过30秒的时间来完成给定的请求,我们建议将该工作转移到后台任务或worker,以便定期ping服务器以查看处理请求是否已完成。这种模式释放了你的web进程来做更多的工作,并减少了整个应用程序的响应时间。

简短的回答是:不,您不能更改此配置。我建议您调查一下为什么应用程序需要超过30秒的时间来处理该请求。如果耗时超过10秒,你真的应该考虑Heroku帮助中心👆

中建议的步骤。你的问题

你提到你需要这个文件处理。我知道文件处理时间很容易超过30秒。通常我要做的是创建某种任务引用,并将其与状态("处理"、"完成"、"失败")一起保存在数据库中——同时存储原始文件,然后结束用户的请求。这不会花很长时间。然后处理任务…使用另一个端点或websocket连接,用户可以检查任务是否已完成。

使用任务队列

以下只是对解决方案的基本解释-它不是用于copy &粘贴取决于很多因素

路线(端点)

基本上你需要在你的后端有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,finishedfailed

3。下载

app.get('/file/:filename', (req, res) => {
return req.status(200)
.sendFile('./path/to/file/' + req.params.filename);
});
指出

  • 用uuid等随机id重命名传入文件可能是个好主意。所以在自动化过程中更容易使用它们。也可以同时使用随机id作为任务id。

  • 这取决于你想要多大。对于任务队列,有许多不同的库可以帮助您。它可以是一个内存队列,也可以是一个由数据库支持的队列。