django - Apache 在响应 gzip 压缩请求时出现滞后

标签 django apache gzip mod-wsgi mod-deflate

对于我正在开发的应用程序,用户提交带有多部分表单数据(内容类型:multipart/form-data)的压缩 HTTP POST 请求(内容编码:GZIP)。我使用 mod_deflate 作为输入过滤器来解压缩,并通过 mod_wsgi 在 Django 中处理 Web 请求。

总的来说,一切都很好。但对于某些请求(确定性),从请求到响应几乎有一分钟的延迟。调查显示 django 中的处理立即完成,但服务器的响应停滞。如果请求未经过 GZIP 压缩,则一切正常。

请注意,为了处理 mod_wsgi 中的故障,我将 content-length 设置为未压缩的消息大小。

有人遇到过这个问题吗?有没有办法在 apache 处理响应时轻松调试它?

最佳答案

您认为 mod_wsgi 中存在什么故障?

事情的简单事实是 WSGI 1.0 不支持改变请求内容的内容长度的变异输入过滤器。因此,从技术上讲,在使用 WSGI 1.0 时,您不能在 Apache 中使用 mod_deflate 来获取请求内容。您将内容长度设置为实际大小以外的值很可能会堵塞 mod_deflate 的操作。

如果您希望能够处理压缩请求内容,您需要超越 WSGI 1.0 规范并使用非标准代码。

我建议您阅读:

http://blog.dscpl.com.au/2009/10/details-on-wsgi-10-amendmentsclarificat.html

这解释了这个问题以及有关它的建议。

我强烈建议您将此问题提交给官方 mod_wsgi mailing list讨论如何编写代码。然而,如果您使用的是 Python 框架之一,您的操作可能会受到限制,因为它们将实现 WSGI 1.0,而您则无法执行此操作。


更新1

从mod_wsgi列表的讨论来看,原始的WSGI应用程序应该包装在以下WSGI中间件中。这仅适用于实际上提供空字符串作为输入结束标记的 WSGI 适配器,这是 WSGI 1.0 不需要的。这可能只适用于小型上传,因为所有内容都被读入内存。如果需要大量压缩上传,则应将累积的数据写出到文件中。

class Wrapper(object):

    def __init__(self, application):
        self.__application = application

    def __call__(self, environ, start_response):
        if environ.get('HTTP_CONTENT_ENCODING', '') == 'gzip':
            buffer = cStringIO.StringIO()
            input = environ['wsgi.input']
            blksize = 8192
            length = 0

            data = input.read(blksize)
            buffer.write(data)
            length += len(data)

            while data:
                data = input.read(blksize)
                buffer.write(data)
                length += len(data)

            buffer = cStringIO.StringIO(buffer.getvalue())

            environ['wsgi.input'] = buffer
            environ['CONTENT_LENGTH'] = length

        return self.__application(environ, start_response)


application = Wrapper(original_wsgi_application_callable)

关于django - Apache 在响应 gzip 压缩请求时出现滞后,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1559416/

相关文章:

django - 在 Django 管理页面上添加链接和按钮

php - 错误加载 opcache.so : opcache. 所以 : undefined symbol: compiler_globals - Apache 2. 4/PHP 5.5/Ubuntu 12.10 VPS 失败

regex - htaccess RewriteCond 问题

node.js - 如何使用 zlib 和 nodejs 压缩和解压缩 .tar.gz

xcode - Xcode 7.0 中的 zlib

python - 从 META 类动态创建 related_name

python - 在 Django 中使用 '_id'

python - 在django模板中将str转换为int

html - 创建三列提要布局

c# - 解压错误: The magic number in GZip header is not correct