4

nginx-> gunicorn-> Django アプリに対して HTTP POST リクエストを実行しています。応答本文はすぐに返されますが、さらに約 60 秒間、要求が完全に終了しません。

「完全に終了」とは、私が試したさまざまなクライアント (Chrome、wget、作成中の Android アプリ) が、追加のデータを待っているかのように、要求がまだ進行中であることを示していることを意味します。Wireshark からリッスンすると、すべてのデータがすばやく到着し、60 秒後に ACK FIN が最終的に到着することがわかります。

ローカル開発サーバー ( ./manage.py runserver) で同じ POST 要求がすばやく実行されます。また、nginx をバイパスして、gunicorn に対して直接実行します。また、Apache/mod_wsgi セットアップですばやく動作します。

GET リクエストには問題はありません。他の POST リクエストでも問題ありません。私が認識している違いの 1 つは、この特定のリクエストが 200 ではなく 201 を返すことです。

ヘッダー、閉じた接続とキープアライブ接続に関係があるContent-Lengthと思いますが、どのように正しく動作するのかまだわかりません。

  • バックエンド サーバー (gunicorn) は現在接続を閉じています。これは理にかなっています。
  • バックエンド サーバーにContent-Length header、または を含める必要がありますかTransfer-encoding: chunked? それとも、nginx はこれらがなくても対応でき、必要に応じて追加できるはずですか?
  • 接続のキープアライブは有効であり、nginx で無効にすべきではないと思います。

更新:keepalive_timeoutを 0 に設定するとnginx.conf問題が解決します。しかし、もちろん、キープアライブはなくなりました。何が問題なのかまだわかりません。おそらく、スタック内の何か (私の Django アプリまたは gunicorn) がチャンク転送を正しく実装しておらず、クライアントを混乱させています。

4

1 に答える 1

0

アップストリームサーバー(gunicorn)がその特定のAPI呼び出しで接続を開いたままにしているようです-理由はわかりませんが(コードによって異なります)、proxy_read_timeoutnginxのデフォルトオプションは60秒なので、なんらかの理由で、この応答が受信されていないようです。

私は非常によく似た設定を使用していますが、POSTに関する問題や、その他の要求には気づいていません。

以前に問題が発生したことに注意しreturn HttpResponse(status=201)てください-Djangoは明示的に空の本体を好むようです:return HttpResponse("", status=201)動作します。私は通常、私が期待されている場所に何かを設定します-これは注意すべきことかもしれません。

于 2012-05-10T08:57:45.127 に答える