上流サーバーのタイムアウトでnginxがPUTまたはPOSTリクエストを再試行するのを停止するにはどうすればよいですか?


11

nginxを使用して、アプリケーションへの要求を負荷分散します。要求がタイムアウトすると、nginxは別のアップストリームサーバーに切り替えることがわかりました(良好)。ただし、これは、望ましくない結果(データが2回保存される)を引き起こす可能性のあるPUTおよびPOST要求に対して行います。タイムアウト時にGETリクエストのみを再試行するようにnginxを設定することは可能ですか?または、問題を解決する別の方法はありますか?

構成は次のとおりです。

upstream mash {
    ip_hash;
    server 127.0.0.1:8081;
    server 192.168.0.11:8081;
}

server {
    ...
    location / {
        proxy_pass http://mash/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;        
    }
}

回答:



6

私はゲームにかなり遅れていることを知っていますが、私にとってこれはこの問題を検索するときの最高の結果ですので、私のソリューションを共有したいと思いました。

これは、カスタムエラーハンドラーと組み合わせたifディレクティブ(いくつかの有効なユースケースの 1つ)を使用します

upstream backend {
    server backend1;
    server backend2;
}

server {
    server_name proxy;

    location / {
        error_page 598 = @retry;
        error_page 599 = @no_retry;
        if ($request_method = POST) {
            return 599;
        }
        return 598;
    }

    location @retry {
        proxy_pass http://backend;
    }

    location @no_retry {
        proxy_pass http://backend;
        proxy_next_upstream off;
    }
}

4

ドキュメントについてはこちらをご覧ください:proxy_next_upstream

これは未検証の要点であることに注意してください

https://gist.github.com/wojons/6154645


実際には機能しませんでした:Nginxは「proxy_next_upstreamはここでは許可されていません」と言います。ifブロックをロケーションに移動しようとしましたが、同じエラーが発生しました。どちらかの場所で「proxy_next_upstream error」を使用すると、独自に機能します。
デビッドティンカー

ロケーションコンテキストで機能することが明確に記載されているドキュメントがあるため、これは非常に奇妙です
-WojonsTech

nginxのは好きではないことをproxy_next_upstreamの周りであれば(...){}のようです
デヴィッド・ティンカー

誰もこれをテストしましたか?4つの賛成票がありますが、ここでは有効なユースケースに準拠していないようです:nginx.com/resources/wiki/start/topics/depth/ifisevil
EoghanM

0

使用proxy_methodディレクティブ

参照:http : //nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_method


2
一般的には、それが明示的に有用であるとのリンクに頼らないように、あなたの答えのリンクから有用な情報を含めることをお勧めします
BE77Y

1
サーバー障害へようこそ!これは理論的には質問に回答するかもしれませんが、回答の重要な部分をここに含め、参照用のリンクを提供することが望ましいでしょう
マークヘンダーソン

-1

Tomcatサーバーにも同じ問題があります。長いリクエストが発生するとプロキシがタイムアウトします。proxy_read_timeoutを使用して問題を解決しました。タイムアウトを増やすと、リクエストがタイムアウトすることはなく、問題は発生しませんでした。デフォルトのタイムアウトは60秒です。参照

location / {
    proxy_pass  http://xxxxxxxxxx.com;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_set_header X-Forwarded-Proto https;
            proxy_redirect off;
            proxy_connect_timeout      800;
            proxy_send_timeout         800;
            proxy_read_timeout         240;     
}

1
これは質問にまったく答えません。あなたの問題は似たようなものではありません。
スヴェン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.