web-dev-qa-db-ja.com

uwsgi + nginx +フラスコ:上流が時期尚早に閉じられた

flaskにエンドポイントを作成しました。これは、データベースクエリ(リモートデータベース)からスプレッドシートを生成し、それをダウンロードとしてブラウザに送信します。Flaskエラーをスローしないでください。Uwsgiは文句を言いません。

しかし、nginxのerror.logを確認すると、多くの情報が表示されます。

2014/12/10 05:06:24 [エラー] 14084#0:* 239436アップストリームから応答ヘッダーを読み取っているときに、アップストリームが接続を途中で閉じました。クライアント:34.34.34.34、サーバー:me.com、リクエスト: "GET/download/export .csv HTTP/1.1 "、アップストリーム:" uwsgi://0.0.0.0:5002 "、ホスト:" me.com "、リファラー:" https://me.com/download/export.csv "

私はuwsgiを次のように展開します

uwsgi --socket 0.0.0.0:5002 --buffer-size=32768 --module server --callab app

私のnginx設定:

server {
     listen 80;
     merge_slashes off;
     server_name me.com www.me.cpm;

     location / { try_files $uri @app; }
       location @app {
          include uwsgi_params;
          uwsgi_pass 0.0.0.0:5002;
          uwsgi_buffer_size 32k;
          uwsgi_buffers 8 32k;
          uwsgi_busy_buffers_size 32k;
     }

}

server {
      listen 443;
      merge_slashes off;
      server_name me.com www.me.com;

    location / { try_files $uri @app; }
       location @app {
          include uwsgi_params;
          uwsgi_pass 0.0.0.0:5002;
          uwsgi_buffer_size 32k;
          uwsgi_buffers 8 32k;
          uwsgi_busy_buffers_size 32k;
       }
}

これはnginxまたはuwsgi、あるいはその両方の問題ですか?

8
user299709

Nginx.confを変更して含める

sendfile        on;
client_max_body_size 20M;
keepalive_timeout  0;

完全な例については、自己回答を参照してください Amazonlinuxのuwsgiupstart

6
tourdownunder

@mahdixで説明されているように、エラーは、uwsgiがそのポートでhttpパケットをリッスンしているときに、Nginxがuwsgiプロトコルでリクエストを送信することによって発生する可能性があります。

Nginx構成では、次のようなものがあります。

upstream org_app {
    server              10.0.9.79:9597;
}
location / {
    include         uwsgi_params;
    uwsgi_pass      org_app;
}

Nginxはuwsgiプロトコルを使用します。しかし、uwsgi.ini次のようなものがあります(またはコマンドラインで同等のもの):

http-socket=:9597

uwsgiはspeakhttpを実行し、質問に記載されているエラーが表示されます。 ネイティブHTTPサポート を参照してください。

考えられる修正は、代わりに次のようにすることです。

socket=:9597

この場合、Nginxとuwsgiは、TCP接続を介してuwsgiプロトコルを使用して相互に通信します。

補足:Nginxとuwsgiが同じノードにある場合、UnixソケットはTCPよりも高速になります。 ポートの代わりにUnixソケットを使用 を参照してください。

3
Ivan Ogai

私の場合、問題は、uwsgiがそのポートでhttpパケットをリッスンしているときに、nginxがuwsgiプロトコルでリクエストを送信していたことでした。そのため、nginxがuwsgiに接続する方法を変更するか、uwsgiプロトコルを使用してリッスンするようにuwsgiを変更する必要がありました。

2
mahdix

このエラーメッセージの背後には多くの原因があるようです。 uwsgi_passを使用していることは承知していますが、proxy_passを使用しているときに長いリクエストで問題が発生する場合は、uWSGIでhttp-timeoutを設定すると役立つ場合があります(ハラキリ設定ではありません)。

1
krzychu

uwsgi_pass 0.0.0.0:5002;uwsgi_pass 127.0.0.1:5002;に置き換えるか、unixソケットを使用することをお勧めします。

1
jwalker

ElasticBeanstalk単一コンテナーのDockerWSGIアプリのデプロイでも同じ散発的なエラーが発生しました。環境のEC2インスタンスでは、アップストリーム設定は次のようになります。

upstream docker {
    server 172.17.0.3:8080;
    keepalive 256;
}

このデフォルトのアップストリームの単純な負荷テストでは、次のようになります。

siege -b -c 16 -t 60S -T 'application/json' 'http://Host/foo POST {"foo": "bar"}'

... EC2では、約70%の可用性が得られました。残りはアップストリームから応答ヘッダーを読み取っているときにアップストリームが接続を途中で閉じたによって引き起こされた502エラーでした。

解決策は、アップストリーム構成からkeepalive設定を削除するか、--http-keepaliveを使用してuWSGI側でもHTTPキープアライブを有効にすることです。 ( 1.9以降で使用可能 )。

0
saaj

Uwsgiでsocket-timeout = 65(uwsgi.iniファイル)または--socket-timeout=65(uwsgiコマンドライン)オプションを渡すことで、この問題を修正しました。 Webトラフィックに応じて異なる値で確認する必要があります。私の場合、uwsgi.iniファイルのこの値socket-timeout = 65は機能しました。

0
Sathish