【问题标题】:Flask, Gunicorn, Nginx :: IOError: [Errno 32] Broken pipeFlask, Gunicorn, Nginx :: IOError: [Errno 32] Broken pipe
【发布时间】:2018-01-15 22:28:41
【问题描述】:

我正在尝试将项目从开发转移到生产。 (在开发阶段,我只使用Flask,现在我在GunicornNginx 后面运行它。)

我在提供特定页面 songs.html 时遇到问题。

页面使用虚拟变量 (jukebox = [whatever]) 正确加载,但在现实生活中我使用的是生成器,如下所示:

playlist= query_playlist(p)
jukebox = next(playlist)

return render_template('songs.html',
                        jukebox=jukebox)

而且这个函数需要一段时间(比如 2 秒)才能返回结果...但是没有提供结果,并且在返回结果后进程会挂起。

我像这样运行应用程序:

(appenv)$gunicorn -c gconfig.py app:app

wsgi.ppy

from app import app as application

if __name__ == "__main__":
    application.run(host='0.0.0.0')

gconfig.py:

workers = 16
worker_class = 'sync'
worker_connections = 1000
timeout = 120 # changed this from 30 up
keepalive = 2

nginx.confbrew 安装)

server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
        proxy_pass         http://127.0.0.1:8000/;
        proxy_redirect     off;

        proxy_set_header   Host                 $host;
        proxy_set_header   X-Real-IP            $remote_addr;
        proxy_set_header   X-Forwarded-For      $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto    $scheme;
        }

如果我使用python app.py 运行应用程序,则返回开发阶段:

if __name__ == '__main__':
    app.run(use_reloader=True, threaded=True, debug=True)

至少我得到以下回溯:

Error on request:
Traceback (most recent call last):
  File "/Users/me/Documents/Code/Apps/app/appenv/lib/python2.7/site-packages/werkzeug/serving.py", line 270, in run_wsgi
    execute(self.server.app)
  File "/Users/me/Documents/Code/Apps/app/appenv/lib/python2.7/site-packages/werkzeug/serving.py", line 261, in execute
    write(data)
  File "/Users/me/Documents/Code/Apps/app/appenv/lib/python2.7/site-packages/werkzeug/serving.py", line 236, in write
    self.send_header('Server', self.version_string())
  File "/Users/me/anaconda2/lib/python2.7/BaseHTTPServer.py", line 412, in send_header
    self.wfile.write("%s: %s\r\n" % (keyword, value))
IOError: [Errno 32] Broken pipe

那么有人知道如何解决这个问题吗?

编辑

即使处理结果需要 2 秒,我也会得到相同的回溯。

【问题讨论】:

  • 由于耗时过长,套接字已从客户端站点关闭。这导致Broken pipe。一般来说,保持响应时间较短。超过 1s 的所有内容都对用户体验不利,超过 3s 的所有内容都需要特殊考虑,例如使用什么 gunicorn worker 类型以及如何防止这成为 DoS 攻击媒介。
  • 您可以尝试流式传输结果,而不是在内存中生成响应然后为其提供服务
  • 我该怎么做呢?你能给我指路吗?
  • @KlausD。我懂了。实际上,这是一个在最后阶段将在后台运行的进程。
  • @KlausD。实际上,即使只有 1 秒,我也能得到相同的回溯......它无论如何都会中断。

标签: python nginx flask gunicorn


【解决方案1】:

根据 Flask docs(并遵循 #arielnmz 建议),您可以流式传输您的内容:

from flask import Response, stream_with_context

@app.route('/playlist')
def generate_playlist():
    def generate():
        jukebox = query_playlist(p)
        for i in jukebox:
            yield i[0]['artist'] 
    return Response(stream_with_context(generate()))

每个yield表达式都直接发送到浏览器。

诀窍是拥有一个内部函数,该函数使用生成器生成数据,然后调用该函数并将其传递给响应对象。

这行得通。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-24
    • 2022-11-10
    • 2021-01-22
    • 2016-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多