Django:Flaky文件下载

时间:2013-02-24 22:51:46

标签: django

我制作了一个简单的文件服务器,运行在我的树莓派(1/2 gb RAM,1个CPU)上。它在nginx(1名工人)后面的gunicorn(3名工人)下运行。

我有一个奇怪的问题,当我尝试同时下载太多文件(比如5)时,他们都会通过一部分然后中止。 django服务器没有输出(我使用开发服务器也遇到了这个问题,这就是为什么它现在在gunicorn& nginx后面运行,但仍然没有欢乐)。

我的下载视图是:

@never_cache
def download_media(request, user_id, session_key, id, filepath):
    "Download an individual media file"

    context = RequestContext(request)

    # validate the user_id & session_key pair
    if not __validate_session_key(user_id, session_key):
        return HttpResponseRedirect(reverse('handle_logout'))

    filepath = unicode(urllib.unquote(filepath))

    if '..' in filepath:
        raise SuspiciousOperation('Invalid characters in subdir parameter.')

    location = MediaCollectionLocation.objects.get(id=id)

    path = os.path.join(location.path, filepath)

    response = HttpResponse(FileWrapper(file(path)), content_type='application/octet-stream')
    response['Content-Disposition'] = 'attachment; filename=%s' % os.path.basename(path)

    response['Content-Length'] = os.path.getsize(path)
    response["Cache-Control"] = "no-cache, no-store, must-revalidate"
    return response

我以这种方式提供文件,因为我希望客户端进行身份验证(所以不要只想重定向并使用nginx提供静态内容)。

如果我并行提出多个请求,任何人都知道为什么会退出?

1 个答案:

答案 0 :(得分:0)

我不完全确定为什么这些文件会失败,但我认为它与下载更多文件有关,而不是工作者,或者nginx和gunicorn之间发生了超时。< / p>

只有在django通过使django设置了nginx然后读取的特定标头(仅限内部)并为文件本身提供服务之后,才能让nginx为文件提供服务。

XSendFile是nginx用来做这件事的。然后,您可以创建一些中间件或一个函数来设置django中的相应头,或者使用类似django-sendfile的内容和nginx后端来完成所有操作。

如果你遇到的问题是由django和nginx之间的超时引起的,那么这个修补程序应该解决它。如果没有,也增加nginx工作者的数量,因为它现在负责提供文件。