web-dev-qa-db-ja.com

nginx proxy_passが接続を閉じるのはなぜですか?

ドキュメントには次のように書かれています

プロキシのHTTPプロトコルバージョンを設定します。デフォルトでは、バージョン1.0が使用されます。キープアライブ接続およびNTLM認証での使用には、バージョン1.1が推奨されます。

私のnginx設定では私が持っています

    location / {
        proxy_http_version 1.1;
        proxy_pass http://127.0.0.1:1980;
    }

http://127.0.0.1:198 を直接実行すると、1つの接続でアプリが(更新時に)多くのリクエストを受け取ることがわかります。これは私が送信する応答です

HTTP/1.1 200 OK\nContent-Type:text/html\nContent-Length:14\nConnection:keep-alive\n\nHello World!

ただし、nginxは1つの要求を行い、それを閉じます。 WTH? nginxが "Connection:keep-alive"ヘッダーを送信することがわかります。サーバーと日付ヘッダーが追加されていることがわかります。追加してみましたproxy_set_header Connection "keep-alive";しかし、それは役に立ちませんでした。

どのようにしてnginxにすべてのスレッドの接続を閉じさせないのですか?

6
user34537

Nginxが接続を維持するには、次の構成が必要です。

  • 適切なヘッダーを構成します(HTTP 1.1および接続ヘッダーには「閉じる」値が含まれていません。実際の値は関係ありません。キープアライブまたは空の値のみです)

  • キープアライブ命令でアップストリームブロックを使用してください。proxy_passurlが機能しません

  • オリジンサーバーでキープアライブを有効にする必要があります

したがって、次のNginx構成ではキープアライブが機能します。

upstream { 
  server 127.0.0.1:1980; 
  keepalive 64; 
}; 

server { 
  location / { 
    proxy_pass http://upstream; 
    proxy_set_header Connection ""; 
    proxy_http_version 1.1; 
  } 
}

RFC-793セクション3.5 に従って、Originサーバーが接続を終了しないことを確認してください。

A TCP接続は、2つの方法で終了する可能性があります。(1)通常のTCP FINハンドシェイクを使用したクローズシーケンス、および(2)「中止」 1つ以上のRSTセグメントが送信され、接続状態はすぐに破棄されます。TCP接続がリモートサイトによって閉じられた場合、ローカルアプリケーションは、正常に閉じられたか、中止されたかを通知する必要があります。

Stackoverflowの 他の答え で、もう少し詳細を見つけることができます。

6
Anatoly

キープアライブは、直接のproxy_pass http:// ip:port ではなく、上流のブロックで有効にする必要があります。

HTTPの場合、proxy_http_versionディレクティブを「1.1」に設定し、「Connection」ヘッダーフィールドをクリアする必要があります

このような:

upstream keepalive-upstream {
    server 127.0.0.1:1980;
    keepalive 23;
}

 location / {
    proxy_http_version 1.1;
    proxy_set_header Connection ""; 
    proxy_pass http://keepalive-upstream;
}
3
wow qing