在 Heroku 上使用 Django 将大文件上传到 AWS S3 存储桶而没有 30 秒的请求超时

Posted

技术标签:

【中文标题】在 Heroku 上使用 Django 将大文件上传到 AWS S3 存储桶而没有 30 秒的请求超时【英文标题】:Uploading Large files to AWS S3 Bucket with Django on Heroku without 30s request timeout 【发布时间】:2017-01-25 13:16:11 【问题描述】:

我有一个允许用户上传视频的 django 应用程序。它托管在 Heroku 上,上传的文件存储在 S3 存储桶上。 在从 Django 应用程序获得预签名请求后,我正在使用 javascript 将文件直接上传到 S3。这是由于 Heroku 30s 请求超时。 无论如何,我可以通过 Django 后端上传大文件而不使用 JavaScript 并影响用户体验吗?

【问题讨论】:

我认为本文涵盖了您的需求,并且适用于非 heroku 环境。 devcenter.heroku.com/articles/s3-upload-python 您是否在使用适用于 javascript 的 AWS 开发工具包?用户体验不应受到影响,看起来前端可以根据AWS SDK for javascript documentation on creating a photo album 完全定制。唯一的区别是上传视频和照片。另外,您为什么认为用户体验会受到影响?以上听起来是解决问题的最具成本效益的技术有效和正确的方法。 【参考方案1】:

另一个答案中的点是有效的。 “无论如何,我是否可以在不使用 JavaScript 的情况下通过 Django 后端上传大文件”这个问题的简短回答是“不离开 Heroku”。

请记住,传输到您的测功机的任何数据都会通过 Heroku 的路由网格,这就是强制 30 秒请求限制以节省其自身有限资源的原因。任何类型的长时间运行的事务都会占用可用于服务其他请求的带宽/计算/等,因此 Heroku 应用限制来帮助保持事情在数千个测功机上移动。上传文件时,您首先会受到客户端到服务器的带宽的限制。然后,除了您的测功机实际执行的任何处理之外,您将受到测功机和 S3 之间的带宽的限制。

文件越大,传输数据超过 30 秒超时的可能性就越大,尤其是在第 1 步中对于不可靠网络上的客户端。创建从客户端到 S3 的直接路径是一种合理的折衷方案。

【讨论】:

【参考方案2】:

您应该考虑以下几点来解决您的问题。

为什么你的文件不应该先到你的 django-server 然后转到 s3:将文件发送到 django 服务器然后将它们发送到 s3 只是浪费计算能力和带宽。下一个问题是,当您可以直接将文件发送到您的 s3 存储时,为什么要将文件发送到 django 服务器。 如何在不影响用户体验的情况下将文件上传到 s3:将文件发送到 django 服务器当然不是一种选择,因此您必须在前端处理此问题。但是前端有它自己的限制,比如内存有限。它无法处理非常大的文件,因为所有内容都加载到 RAM 中,如果文件非常大,浏览器最终将耗尽内存。我建议你使用类似dropzone.js 的东西。它不会解决内存问题,但它肯定可以为用户提供良好的 UX,例如显示进度条、文件数量等。

【讨论】:

从浏览器上传会带来安全风险,不是吗?你最终不会暴露秘密和 api 密钥吗? 当然可以,但您必须在浏览器的情况下使用临时凭据。这些凭据具有访问策略和到期时间,因此不会构成安全威胁。您可以在 aws S3 文档中找到有关它的更多信息 在这种情况下不会“流式传输”文件吗?我不熟悉 AWS JS SDK,但是如果上传和 S3 处理程序都可以被视为套接字,那么它只是从一个读取并写入另一个的情况,然后关闭两者 Sockets 并不是唯一用于此目的的东西。在这个问题的上下文中流式传输文件是什么意思。因为它是一个文件,所以它只能被流式传输,你不能通过流式传输整个文件。 @omu_negru 仅公开了 api 密钥(这没关系,无论如何它应该包含在所有请求中)。您将密钥保存在服务器上的 Django 应用程序 / 中,并使用它来生成浏览器使用的临时签名 URL。

以上是关于在 Heroku 上使用 Django 将大文件上传到 AWS S3 存储桶而没有 30 秒的请求超时的主要内容,如果未能解决你的问题,请参考以下文章

在 Heroku 上部署 Django/静态文件的正确方法

找不到静态文件 - 在 Heroku 上部署 Django

使用 AWS S3 for django 在 heroku 上提供静态文件?

在heroku上部署django网站时出错

Heroku 上带有 gunicorn 服务器的 Django 项目不提供静态文件

在 Heroku 服务器上部署 Django 错误 (500) - 据说是静态文件问题