简体   繁体   English

Flask,Gunicorn,Nginx :: IOError:[Errno 32]管道破裂

[英]Flask, Gunicorn, Nginx :: IOError: [Errno 32] Broken pipe

I'm trying to move a project from development to production. 我正在尝试将项目从开发转移到生产。 (At dev stage, I was using only Flask , and now I'm running it behind Gunicorn with Nginx .) (在开发阶段,我只使用Flask ,现在我用NginxGunicorn后面运行它。)

I'm having a problem to serve a specific page, songs.html . 我在服务特定页面时songs.html问题, songs.html

The page loads correctly with a dummy variable ( jukebox = [whatever] ), but in real life I'm using a generator, like so: 页面正确加载虚拟变量( jukebox = [whatever] ),但在现实生活中我使用的是生成器,如下所示:

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

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

and this function takes a while (say 2s) to return results...but results are not being served, and process just hangs after results are returned. 并且此函数需要一段时间(比如2s)才能返回结果...但是没有提供结果,并且进程只是在返回结果后挂起。

I run the app like so: 我像这样运行应用程序:

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

wsgi.ppy wsgi.ppy

from app import app as application

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

gconfig.py: gconfig.py:

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

nginx.conf ( brew installation) 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;
        }

If I run the app using python app.py , back to dev stage: 如果我使用python app.py运行应用程序,请返回dev阶段:

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

at least I get the following traceback: 至少我得到以下回溯:

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

so does anyone know how to fix this? 那么有谁知道如何解决这个问题?

EDIT 编辑

I get the same traceback even with results taking 2s to be processed. 即使结果需要处理2秒,我也会获得相同的回溯。

According to Flask docs (and following #arielnmz sugestion), you can stream your content: 根据Flask docs (以及#arielnmz sugestion),您可以流式传输您的内容:

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()))

Each yield expression is directly sent to the browser. 每个yield表达式都直接发送到浏览器。

The trick is to have an inner function that uses a generator to generate data and to then invoke that function and pass it to a response object. 诀窍是有一个内部函数,它使用生成器生成数据,然后调用该函数并将其传递给响应对象。

This works. 这有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM