Nginx uWSGI 响应被截断

Nginx uWSGI 响应被截断

今天我试着写一个 web 服务,作为一个笑话http://dont-tread-on-memes.controversial.io。这是一个 Flask 应用程序,用于处理相当大的图像。Flask 应用程序本身运行良好,独立的 uWSGI 服务器也一样,但是当我尝试通过 将 uWSGI 插入 NGINX 时uwsgi_pass,突然间所有请求在浏览器中都被截断为 9.99KB。

在阅读了有关类似截断的文章后,proxy_pass我尝试了:

  1. 在我的配置文件中设置uwsgi_bufferingoff
  2. 将缓冲区大小1024k增加到uwsgi_buffers 1024 1024k; uwsgi_buffer_size 1024k;
  3. sendfile: off
  4. 检查缓冲区文件权限(其中的所有文件/var/lib/uwsgi都归用户www-datawww-data组所有,所以我认为我的权限很好。)

我保留了当前的配置,但仍然出现以下问题:

server {
    listen 80;
    server_name dont-tread-on-memes.controversial.io;

    location / {
        include uwsgi_params;
        uwsgi_pass unix:/var/www/dont-tread-on-memes/dont_tread_on_memes.sock;
        uwsgi_buffers 1024 1024k;
        uwsgi_buffer_size 1024k;
    }
}

最奇怪的是,这个问题只出现在每个第二个请求中。这一定与 NGINX 缓存有关,因为我没有使用多个 NGINX 实例或其他任何东西。然而,这一定与我的 NGINX 配置有关,因为单独运行的 uWSGI 不会出现此问题。

对于导致此问题的原因和解决方法,您有什么想法吗?

答案1

在仔细检查uwsgi我测试的命令是否与我在文件中提供的所有选项相匹配后.ini,我意识到我的.ini文件包含processes = 5,而uwsgi我测试的命令却不包含。如果我--processes=5uwsgi命令中添加,我可以在每一个命中,而不仅仅是在每一个第二个请求上。每次我uwsgi用启动服务器时--processes=5,第一个请求成功,第二个请求产生 500,并且所有后续请求都被截断为 9.99MB,控制台中出现以下错误:

[2017-01-08 04:16:08,959] ERROR in app: Exception on / [GET]
Traceback (most recent call last):
  File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1982, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1614, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1517, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.4/dist-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1612, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1598, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "./flaskapp.py", line 13, in main
    flag = dont_tread_on_memes.dont_me(caption)
  File "./dont_tread_on_memes/__init__.py", line 30, in dont_me
    return tread_on("don't {} me".format(phrase))
  File "./dont_tread_on_memes/__init__.py", line 16, in tread_on
    flag = BLANK_FLAG.copy()
  File "/usr/local/lib/python3.4/dist-packages/PIL/Image.py", line 1010, in copy
    self.load()
  File "/usr/local/lib/python3.4/dist-packages/PIL/ImageFile.py", line 226, in load
    "(%d bytes not processed)" % len(b))
OSError: image file is truncated (0 bytes not processed)

我怀疑这是 Pillow 和处理线程的方式的问题uwsgi。也许每隔一个请求的行为是由于方式uwsgi决定生成新进程并终止旧进程,或者是由于 NGINX 的缓存。无论如何,我已经修复了截断问题。

我还发现在 StackOverflow 上,有和我一样问题的人提到了这一点。

如果其他人可以回答为什么会发生这种情况,或者回答如何既能保持此问题得到解决又能uwsgi产生多个进程,我肯定会认为这是一个更完整的答案并接受它。

答案2

这几乎总是意味着你的图片有问题(即底部缺少数据)。我使用 PIL 处理过大于 25mb 的图片(前提是你有足够的 RAM),效果很好。解决方法在这里可能对你有用。复制并粘贴以方便阅读:

if img and img.meta_type == 'Image':
    pilImg = PIL.Image.open( StringIO(str(img.data)) )
elif imgData:
    pilImg = PIL.Image.open( StringIO(imgData) )

try:
    pilImg.load()
except IOError:
    pass # You can always log it to logger

答案3

我遇到了类似的问题。一些 javascript 文件被剪切。设置缓冲区:

uwsgi_buffers 1024 1024k;

uwsgi_buffer_size 1024k;

解决了问题

相关内容