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

nginx - Балансировщик нагрузки - Значительная задержка, когда восходящий узел отключен / не работает

Запуск nginx 1.0.15 на CentOS 6.5. У меня есть три восходящих сервера, и все работает нормально, однако, когда я имитирую сбой и отключаю один из вышестоящих серверов, я замечаю значительную задержку во времени ответа (дополнительные 5-7 секунд). Как только я снова отключаю отключенный сервер, лаг исчезает. Кроме того, я заметил еще одну странную вещь: если я просто остановлю службу httpd на сервере смоделированного сбоя, время отклика будет нормальным, задержка произойдет только в том случае, если сервер полностью отключен.

Вот мой конф:

upstream prod_example_com {

    server app-a-1:51000;

    server app-a-2:51000;

    server app-a-3:51000;

}


server {

    # link:  http://wiki.nginx.org/MailCoreModule#server_name
    server_name example.com www.example.com *.example.com;

    #-----
    # Upstream logic
    #-----


    set $upstream_type prod_example_com;


    #-----

    include include.d/common.conf;

    # Configure logging
    access_log  /var/log/nginx/example/access/access.log access;
    error_log   /var/log/nginx/example/error.log error;

    location / {

        # link: http://wiki.nginx.org/HttpProxyModule#proxy_pass
        proxy_pass  http://$upstream_type$request_uri;

        # link: http://wiki.nginx.org/HttpProxyModule#proxy_set_header
        proxy_set_header    Host    $host;
        proxy_set_header    X-Real-IP   $remote_addr;
        proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;
    }

    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {

        # link: http://wiki.nginx.org/HttpProxyModule#proxy_pass
        proxy_pass  http://$upstream_type$request_uri;

        # link: http://wiki.nginx.org/HttpProxyModule#proxy_set_header
        proxy_set_header    Host    $host;
        proxy_set_header    X-Real-IP   $remote_addr;
        proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;

        proxy_hide_header expires;
        proxy_hide_header Cache-Control

         # Even tho this reads like the older syntax, it is handled internally by nginx to set max age to now + 1 year
         expires max;

        # Allow intermediary caches the ability to cache the asset
        add_header Cache-Control "public";
    }
}

Я пробовал предложения в похожих сообщениях, например этот. И, видимо, моя версия nginx слишком стара, чтобы поддерживать health_checks, как указано в nginx документы. Я также попытался явно установить max_fails=2 и fail_timeout=120 на app-a-3 определение восходящего потока, но ни один из них, похоже, не позволяет избежать дополнительных 5-7 секунд для каждого запроса, если app-a-3 не в сети.

-- Обновить --

По запросу, вот вывод для одного запроса, когда app-a-3 полностью отключен. Единственное, что я увидел необычно, - это задержка в 3 секунды между начальным и последующим событиями.

- Обновление №2 -

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

Как упоминалось в комментариях, мы загружаемся, и у нас нет долларов на контракт на 1350 долларов. Я нашел это репо который обеспечивает функциональность. Хотите знать, есть ли у кого-нибудь опыт работы с этим? Стабильный? Исполнитель?

В худшем случае мне просто придется прикусить пулю и заплатить дополнительные 20 долларов в месяц за Linode «Node Balancer», который, я уверен, основан на Nginx Plus. Единственная проблема заключается в отсутствии контроля над конфигурацией, кроме нескольких общих параметров, поэтому нет возможности поддерживать несколько файлов vhost через один балансировщик, и все узлы должны находиться в одном центре обработки данных.

- Обновление №3 -

Вот некоторые результаты осады. Похоже, что второй узел неправильно настроен, поскольку он может обрабатывать только около 75% запросов, которые обрабатываются первым и третьим узлами. Также мне показалось странным, что когда я отключил второй узел, производительность была такой плохой, как если бы я отключил третий (более эффективный) узел. Логика подсказывает, что, если я удалю слабое звено (второй узел), я получу лучшую производительность, потому что оставшиеся два узла работают лучше, чем слабое звено по отдельности.

Коротко:

node 1, 2, 3 + my nginx = 2037 requests

node 1, 2 + my nginx  = 733 requests

node 1, 3 + my nginx = 639 requests (huh? these two perform better individually so together should be somewhere around ~1500 requests, based on 2000 requests when all nodes are up)

node 1, 3 + Linode Load Balancer = 790 requests

node 1, 2, 3 + Linode Load Balancer = 1,988 requests

Если nginx отправляет запрос на закрытый порт на сервере с работающим IP-стеком, он немедленно получит отрицательное подтверждение. Если нет сервера для ответа (или если вы отбрасываете входящий пакет на брандмауэре), вам придется подождать, пока соединение не истечет.

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

Nginx - не самый сложный из балансировщиков нагрузки. Если вы столкнулись с подобными проблемами, возможно, вам стоит рассмотреть другие варианты.

РЕДАКТИРОВАТЬ: Возможно, что-то вроде этого? http://www.howtoforge.com/setting-up-a-high-availability-load-balancer-with-haproxy-heartbeat-on-debian-lenny . Для небольшой установки нет необходимости в отдельных серверах, просто поместите их в ящики веб-серверов. Это дает балансировку нагрузки, но не кэширование. Существуют также растворы HA, которые контролируют кальмары или лак в ответ на сердцебиение.

Пара вещей, которые вы можете попробовать

  1. Обновите nginx до последней версии из официальных репозиториев http://nginx.org/en/linux_packages.html#stable
  2. Попробуйте уменьшить параметр proxy_connect_timeout, установите для него что-то очень низкое, например 1 секунду. http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_connect_timeout

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

Инженеры NGINX не смогли воссоздать проблему с помощью Apache 2.4.x, поэтому я рекомендую это исправить, если кто-то еще столкнется с такой же ситуацией. Однако в нашем проекте я работаю над тем, чтобы полностью отказаться от Apache и внедрить NGINX с php-fpm.

В заключение, наша среда будет использовать NGINX + (требуется контракт на поддержку) в качестве балансировщика нагрузки из-за его способности проводить проверки работоспособности вышестоящим узлам и выдавать запросы через циклический перебор на вышестоящие узлы, на которых работает NGINX (FOSS).