web-dev-qa-db-ja.com

Nginxリバースプロキシにより504ゲートウェイタイムアウトが発生する

Nginxをリバースプロキシとして使用し、リクエストを取得してproxy_passを実行し、ポート8001で実行されているアップストリームサーバーから実際のWebアプリケーションを取得します。

Mywebsite.comにアクセスするか、wgetを実行すると、60秒後に504ゲートウェイタイムアウトが発生します...ただし、mywebsite.com:8001を読み込むと、アプリケーションは期待どおりに読み込まれます。

そのため、Nginxがアップストリームサーバーと通信するのを妨げています。

これはすべて、ホスティング会社が私のものが動作しているマシンをリセットした後に始まりました。

ここに私のvhostsサーバーブロック:

server {
    listen   80;
    server_name mywebsite.com;

    root /home/user/public_html/mywebsite.com/public;

    access_log /home/user/public_html/mywebsite.com/log/access.log upstreamlog;
    error_log /home/user/public_html/mywebsite.com/log/error.log;

    location / {
        proxy_pass http://xxx.xxx.xxx.xxx:8001;
        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;
    }
} 

およびNginxエラーログからの出力:

2014/06/27 13:10:58 [error] 31406#0: *1 upstream timed out (110: Connection timed out) while connecting to upstream, client: xxx.xx.xxx.xxx, server: mywebsite.com, request: "GET / HTTP/1.1", upstream: "http://xxx.xxx.xxx.xxx:8001/", Host: "mywebsite.com"
88
Dave Roma

おそらく、さらに数行を追加して、アップストリームへのタイムアウト期間を増やすことができます。以下の例では、タイムアウトを300秒に設定しています。

proxy_connect_timeout       300;
proxy_send_timeout          300;
proxy_read_timeout          300;
send_timeout                300;
125
user2540984

あなたが言うように、実際のターゲットWebサーバーは問題なく応答しているため、タイムアウトを増やしても問題は解決しないでしょう。

これと同じ問題があり、接続でキープアライブを使用しないことに関係していることがわかりました。これがなぜなのか実際に答えることはできませんが、接続ヘッダーをクリアすることでこの問題を解決し、リクエストはうまくプロキシされました:

server {
    location / {
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   Host      $http_Host;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_pass http://localhost:5000;
    }
}

より詳細に説明するこの投稿を見てください: nginxはリクエスト後にアップストリーム接続を閉じますキープアライブヘッダーの明確化http://nginx.org/ ja/docs/http/ngx_http_upstream_module.html#keepalive

48
Almund

すべてのサイトの時間制限を延長または追加する場合は、nginx.confファイルに以下の行を追加できます。

以下の行を/usr/local/etc/nginx/nginx.confまたは/etc/nginx/nginx.confファイルのhttpセクションに追加します。

fastcgi_read_timeout 600;
proxy_read_timeout 600;

上記の行がconfファイルに存在しない場合は追加してください。そうでない場合は、fastcgi_read_timeoutproxy_read_timeoutを増やして、nginxとphp-fpmがタイムアウトにならないようにしてください。

1つのサイトのみの制限時間を延長するには、vim /etc/nginx/sites-available/example.comで編集できます

location ~ \.php$ {
    include /etc/nginx/fastcgi_params;
        fastcgi_pass  unix:/var/run/php5-fpm.sock;
    fastcgi_read_timeout 300; 
}

そして、これらの行をnginx.confに追加した後、nginxを再起動することを忘れないでください。

service php7-fpm reload 
service nginx reload

または、valetを使用している場合は、単にvalet restartと入力します。

9
Adeel

ser2540984 、および他の多くの人が、タイムアウト設定を増やすことができると指摘しています。私自身もこれに似た問題に直面し、/ etc/nginx/nginx.confファイルのタイムアウト設定を変更しようとしました。これらのスレッドのほとんど全員が示唆しています。ただし、これは少しも助けにはなりませんでした。 NGINXのタイムアウト設定に明らかな変更はありませんでした。何時間も検索した後、ようやく問題を解決できました。

解決策は このフォーラムスレッド にあり、タイムアウト設定を/ etc/nginx/confに置く必要があると書かれています.d/timeout.conf(このファイルが存在しない場合は作成する必要があります)。スレッドで提案されているのと同じ設定を使用しました。

proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;

これはあなたの特定の問題の解決策ではないかもしれませんが、タイムアウトが/ etc/nginx/nginx.confで変更されることに他の誰かが気付いた場合、これを期待します答えが役立ちます!

4

アップストリームサーバーがドメイン名を使用し、そのIPアドレスが変更された場合(たとえば、アップストリームがAWS Elastic Load Balancerを指している場合)、この状況に直面することもあります

問題は、nginxがIPアドレスを1回解決し、構成がリロードされるまで後続のリクエストのためにキャッシュを保持することです。

キャッシュされたエントリの有効期限が切れると、nginxにネームサーバーを使用して re-resolve ドメインに指示することができます。

location /mylocation {
    # use google dns to resolve Host after IP cached expires
    resolver 8.8.8.8;
    set $upstream_endpoint http://your.backend.server/;
    proxy_pass $upstream_endpoint;
}

proxy_pass のドキュメントでは、このトリックが機能する理由を説明しています。

パラメーター値には変数を含めることができます。この場合、アドレスがドメイン名として指定されている場合、その名前は記述されたサーバーグループ間で検索され、見つからない場合はリゾルバーを使用して決定されます。

詳細な説明については "Nginx with dynamic upstreams"(tenzer.dk) に感謝します。これには、転送されたURIに関するこのアプローチの警告に関する関連情報も含まれています。

3
el.atomo

同じ問題がありました。上流サーバーでのiptables接続追跡が原因であることが判明しました。ファイアウォールスクリプトから--state NEW,ESTABLISHED,RELATEDを削除し、conntrack -Fでフラッシュすると、問題はなくなりました。

2
mindlab