Warm tip: This article is reproduced from serverfault.com, please click

python-可以在Django中为大型非本地文件流式传输zip吗?

(python - Streaming zip in Django for large non-local files possible?)

发布于 2020-12-07 14:48:53

我有一个用Django编写的代理,它接收对某些文件的请求。在确定是否允许用户查看文件之后,代理从远程服务获取文件并将其提供给用户。还有更多的东西,但这是要点。

此设置非常适合单个文件,但是有一个新要求,即用户希望将多个文件作为zip一起下载。文件有时很小,但也可能变得非常大(超过100MB),并且可以同时存储2到1000个文件。这可能会变得非常大,这是首先获取所有这些文件,将其压缩然后在相同的请求中提供服务的负担。

我了解了创建“流式zip”的可能性。一种打开zip,然后开始发送该zip中的文件的方法,直到将其关闭为止。我找到了几个php示例,在Python中找到了django-zip-stream扩展名它们都假定本地存储的文件,并且django扩展名还假定了nginx的用法。

在我的情况下,我有两件事想知道:

  1. 我没有本地存储的文件。我可以使用异步/等待结构来获取它们并同时为它们提供服务。那将意味着我总是在内存中有两个文件(我当前正在服务的一个文件,以及我从源服务器获取的下一个文件)。
  2. 不幸的是,我无法控制将用于此目的的Web服务器。我当然可以在其前面放置一个nginx容器,但是我认为nginx不能从存储在Python vars中的文件中提供服务,因为我是从源服务器获取它们的。
  3. 无论我是用Python还是用nginx压缩,我都认为所需的CPU周期是相当大的。

有人知道在我的超大型远程文件设置中,流式zip是否是个好主意?我有点担心,由于CPU或内存的限制,许多请求都将轻易地使我们的服务器退出DOS。

我还可以建立一个队列来压缩文件并向用户发送电子邮件,但是如果可能的话,我希望应用程序尽可能保持无状态。

欢迎所有提示!

Questioner
kramer65
Viewed
0
Mario Orlandi 2020-12-12 07:35:49

在我看来,这似乎是一个完美的用例,可以解决在队列中排队并在后台对其进行处理的问题。

好处:

  1. 由于检索和压缩文件需要一个可变的(可能很长的)时间,应该将其与HTTP请求/响应周期分开;
  2. 多个作业将被序列化以在任务队列中执行。

第二个优点是特别理想的,因为你已准备好接收多个并发请求。

我还将考虑使用带有FileField的“任务” Django模型作为生成的zip文件的容器,因此Nginx将通过媒体文件夹静态有效地为其提供服务。另外一个好处是,你将直接从Django管理员用户界面监视正在发生的事情。

我在许多Django项目中都使用了类似的方法,事实证明该方法非常健壮和可管理。你可能想快速浏览一下我正在使用的以下django应用程序:https : //github.com/morlandi/django-task

总结一下:

  • 用FileField编写一个“任务”模型,用作压缩结果的容器
  • 收到请求后,在“任务”表中插入新记录,并在后台队列中插入新作业
  • 后台工作负责收集资源并压缩它们;这是常见的Python东西
  • 完成后,将结果保存在FileField中并向用户发送通知
  • 用户将按照收到的网址将zip文件下载为静态文件