Запуск 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, которые контролируют кальмары или лак в ответ на сердцебиение.
Пара вещей, которые вы можете попробовать
В течение последних нескольких недель я работал с командой предпродажной поддержки NGINX, пытаясь решить эту проблему до покупки контракта на поддержку. После долгой работы и совместной работы единственный вывод, который мы могли сделать для увеличения задержки, когда один узел полностью отключился, заключается в том, что все рассматриваемые серверы работали под гораздо более старым Apache 2.2.
Инженеры NGINX не смогли воссоздать проблему с помощью Apache 2.4.x, поэтому я рекомендую это исправить, если кто-то еще столкнется с такой же ситуацией. Однако в нашем проекте я работаю над тем, чтобы полностью отказаться от Apache и внедрить NGINX с php-fpm.
В заключение, наша среда будет использовать NGINX + (требуется контракт на поддержку) в качестве балансировщика нагрузки из-за его способности проводить проверки работоспособности вышестоящим узлам и выдавать запросы через циклический перебор на вышестоящие узлы, на которых работает NGINX (FOSS).