У меня следующая конфигурация балансировки нагрузки:
upstream upstream {
ip_hash;
keepalive 1000;
server 10.10.10.1;
server 10.10.10.2;
server 10.10.10.3;
}
server {
listen 443;
server_name example.com;
ssl_certificate /etc/nginx/certs/cert.crt;
ssl_certificate_key /etc/nginx/certs/cert.key;
ssl on;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
ssl_prefer_server_ciphers on;
location / {
client_max_body_size 80m;
proxy_http_version 1.1;
proxy_set_header Connection "";
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_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 90;
proxy_pass http://upstream;
}
}
Хотя мои внутренние узлы стабильны, все работает нормально. Однако, когда я выключаю один из узлов (например, 10.10.10.2), NGINX будет продолжать отправлять на него трафик, даже если запросы продолжают время ожидания (поскольку сервер выключен). Я уже пробовал настроить max_fails
и fail_timeout
параметры, но поведение остается прежним.
Может ли NGINX автоматически определять, что сервер не работает, и не отправлять туда трафик? Какая конфигурация мне не хватает?
Идея поддержки активности состоит в том, чтобы решить проблему задержки установления TCP-соединений в сетях с высокой задержкой. Для установления TCP-соединения требуется трехэтапное рукопожатие, поэтому при заметной задержке между клиентом и сервером поддержка активности значительно ускорит процесс за счет повторного использования существующих соединений.
Nginx очень эффективен при манипулировании тысячами подключений, тогда как многие бэкенды этого не делают, поэтому для ускорения работы люди часто ставят nginx перед своими реальными веб-серверами, чтобы ускорить работу, так что соединения между облаком и пользователем будут кешированный keepalive для последующего повторного использования.
Обратите внимание, что nginx даже не поддерживал upstream
keepalive
до 1.1.4, согласно http://nginx.org/r/keepalive, поскольку, как указано выше, с большей вероятностью будет использоваться больше ресурсов вашего восходящего потока, чем для ускорения любой обработки, при условии, что у вас есть задержка менее миллисекунды между всеми вашими хостами (например, между nginx и вышестоящими серверами).
Используя чрезмерное количество соединений keepalive в локальной сети, по несколько сотен на каждый вышестоящий сервер, вы, скорее всего, только замедляете, а не ускоряете работу, даже если у вас не возникла проблема, как вы описываете.
Обычно, когда данный порт недоступен на хосте, хост немедленно возвращает Пакет сброса TCP, известный как RST
, который немедленно сообщает клиенту (например, nginx) о том, что происходит, позволяя ему быстро предпринять соответствующие действия. (Пакеты кроме RST
может также использоваться для того же эффекта, например, когда маршрут к хосту недоступен.)
Если мы остановим службу на бэкэнде, nginx справится с этим правильно. Проблема воспроизводится только при остановке всей виртуальной машины. - Рамиро Беррелеза, 27 октября в 22:48
Ваш вышеупомянутый комментарий, вероятно, указывает на то, что nginx, безусловно, сбивает с толку отсутствие своевременных пакетов с отказом в соединении - похоже, ваша установка может просто отбрасывать пакеты, которые отправляет nginx. И без какого-либо ответа на запросы, как кто-то может узнать, недоступна ли ваша серверная служба, вместо того, чтобы просто демонстрировать поведение на уровне предприятия?
Во-первых, как уже упоминалось, даже если вы не испытывали описанных вами проблем, вы, вероятно, только замедляете работу, используя upstream
keepalive
функциональность в локальной сети, особенно с таким большим числом.
В противном случае вы можете настроить свою настройку (брандмауэр, маршрутизатор, среда виртуализации и т. Д.), Чтобы возвращать соответствующие пакеты для недоступных хостов, что, безусловно, должно заставить nginx работать должным образом, поскольку вы уже сами проверили, что происходит, когда TCP RST пакеты фактически возвращаются хостом.
Другой вариант - настроить различные таймауты в nginx, чтобы учесть возможность бесследного исчезновения ваших восходящих потоков и компенсировать невозможность вашей сети генерировать соответствующие контрольные пакеты.
Это может включать connect(2)
таймаут для установления новых TCP-соединений через http://nginx.org/r/proxy_connect_timeout в миллисекундном диапазоне (например, если все ваши серверы находятся в локальной сети, и вы НЕ используете программное обеспечение корпоративного уровня с мультисекундными задержками корпоративного уровня), а также таймауты для текущих read(2)
и send(2)
операции через http://nginx.org/r/proxy_read_timeout и http://nginx.org/r/proxy_send_timeoutсоответственно, что будет зависеть от того, как быстро ваше внутреннее приложение должно отвечать на запросы. Вы также можете увеличить fail_timeout
параметр server
директива в upstream
контекст, согласно http://nginx.org/en/docs/http/ngx_http_upstream_module.html#server.
Попробуйте установить keepalive 16
и снова протестируем. 1k кешированных соединений на одного рабочего может быть слишком много для вашего случая.