Как мне остановить nginx от повторной отправки запросов PUT или POST по таймауту вышестоящего сервера?

11

Мы используем nginx для загрузки запросов баланса в наше приложение. Мы обнаружили, что nginx переключается на другой вышестоящий сервер по истечении времени ожидания запросов (хорошо). Однако это делается для запросов PUT и POST, что может привести к нежелательным результатам (данные хранятся дважды). Можно ли настроить nginx так, чтобы он только повторял запросы GET по таймауту? Или есть другой способ решить проблему?

Наша конфигурация выглядит следующим образом:

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;        
    }
}
Дэвид Тинкер
источник

Ответы:

9

Это стало поведением по умолчанию, начиная с версии 1.9.13

Чтобы вернуть его обратно вручную, вы можете использовать:

proxy_next_upstream error timeout non_idempotent;
Павел Евстигнеев
источник
6

Я знаю, что уже довольно поздно к игре, но для меня это лучший результат при поиске этой проблемы, поэтому я хотел поделиться своим решением.

При этом используется директива if (с одним из нескольких допустимых вариантов использования ) в сочетании с пользовательским обработчиком ошибок :

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;
    }
}
ddelbondio
источник
4

Пожалуйста, смотрите здесь для документации: proxy_next_upstream

Обратите внимание, что это непроверенная суть

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

WojonsTech
источник
На самом деле это не сработало: Nginx говорит: «proxy_next_upstream здесь не разрешен». Я попытался переместить блоки if на место и получил ту же ошибку. Использование «proxy_next_upstream error» в любом месте само по себе работает.
Дэвид Тинкер
это очень странно, поскольку в документации четко сказано, что она работает в контексте местоположения
WojonsTech
кажется, что if (...) {} вокруг proxy_next_upstream не нравится nginx
David Tinker
Кто-нибудь проверял это? 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

yuankui
источник
2
Как правило, рекомендуется включать в ваш ответ полезную информацию по ссылке, чтобы она явно не зависела от полезной
ссылки
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;     
}
hmtmcse
источник
1
Это не отвечает на вопрос вообще. Ваши проблемы не похожи друг на друга.
Свен