Назад | Перейти на главную страницу

Как заставить Nginx запускать 504 немедленно, если сервер недоступен?

У меня Nginx настроен как балансировщик нагрузки с привязкой на основе файлов cookie. Логика такая:

  1. Если файла cookie НЕТ, используйте циклическое ограбление, чтобы выбрать сервер из кластера.

  2. Если cookie есть, перейдите на сервер, связанный со значением cookie. Затем сервер отвечает за установку файла cookie.

    Я хочу добавить следующее:

  3. Если cookie есть, но сервер не работает, вернитесь к шагу циклического ограбления, чтобы выбрать следующий доступный сервер.

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

Мне удалось это сделать с помощью error_page директива, но она работает не так, как я ожидал.

Эта проблема: 504 (и связанный с ним откат) срабатывает только после 30 секунд ожидания, даже если сервер физически недоступен.

Итак, я хочу, чтобы Nginx немедленно запустил 504 (или любую другую ошибку, не имеет значения) (я полагаю, это означает: когда TCP-соединение не работает). Это поведение, которое мы можем наблюдать в браузерах: если мы переходим непосредственно к серверу, когда он не работает, браузер немедленно сообщает нам, что не может подключиться. Более того, похоже, что Nginx делает это для ошибки 502: если я намеренно неправильно сконфигурирую свои серверы, Nginx немедленно запускает 502.

Конфигурация (сокращено до основ):

http {
    upstream my_cluster {
        server 192.168.73.210:1337;
        server 192.168.73.210:1338;
    }
    map $cookie_myCookie $http_sticky_backend {
        default 0;
        value1   192.168.73.210:1337;
        value2   192.168.73.210:1338;
    }
    server {
        listen 8080;
        
        location @fallback {
            proxy_pass http://my_cluster;
        }

        location / {
            error_page 504 = @fallback;
            
            # Create a map of choices
            # see https://gist.github.com/jrom/1760790
            set $test HTTP;
            if ($http_sticky_backend) {
                set $test "${test}-STICKY";
            }
            
            if ($test = HTTP-STICKY) {
                proxy_pass http://$http_sticky_backend$uri?$args;
                break;
            }
            if ($test = HTTP) {
                proxy_pass http://my_cluster;
                break;
            }
            
            return 500 "Misconfiguration";
        }
    }
}

Отказ от ответственности: Я довольно далек от системного администрирования любого рода, так что, возможно, мне не хватает некоторых основ.

РЕДАКТИРОВАТЬ: Меня интересует решение со стандартной бесплатной версией Nginx, а не Nginx Plus. Спасибо.

upstream appservers {
    zone appservers 64k;

    server appserv1.example.com      weight=5;
    server appserv2.example.com:8080 fail_timeout=5s slow_start=30s;
    server 192.0.2.1                 max_fails=3;

    server reserve1.example.com:8080 backup;
    server reserve2.example.com:8080 backup;
}

Вот так! Из документы

HTH