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

nginx - connect () не удалось выполнить восходящее тестирование при нагрузочном тестировании

Я проводил нагрузочное тестирование с wrk моего обратного прокси-сервера nginx -> настройка моего веб-приложения, и я заметил, что, когда я добираюсь до 1000+ одновременных подключений, nginx начинает возвращать 502 и следующее сообщение об ошибке:

2015/04/17 20:45:26 [crit] 6068#0: *1116212677 connect() to \
127.0.0.1:3004 failed (99: Cannot assign requested address) \
while connecting to upstream, client: xxx.xxx.xx.165, server: \
foo.bar.com, request: "GET /my/route HTTP/1.1", upstream: \
"http://127.0.0.1:3004/my/route", host: "foo.bar.com"

в wrk команда была:

wrk -t10 -c500 -d5m "https://foo.bar.com/my/route" -H "Accept: application/json"

Я пытаюсь понять, что здесь могло пойти не так. Мое веб-приложение прослушивает запросы, проксируемые nginx на порт 3004. У nginx не хватает портов? Разве веб-приложение не может обработать такое количество запросов? Истекло ли время ожидания запросов? Я не совсем понимаю это и хотел бы получить больше информации об этом.

Уже ответили здесь: https://stackoverflow.com/questions/14144396/nginx-proxy-connect-to-ip80-failed-99-cannot-assign-requested-address

Сообщение предполагает, что у вас закончились локальные сокеты / порты.

Попробуйте увеличить сетевые ограничения:

echo "10240 65535" > /proc/sys/net/ipv4/ip_local_port_range
sysctl net.ipv4.tcp_timestamps=1
sysctl net.ipv4.tcp_tw_recycle=0
sysctl net.ipv4.tcp_tw_reuse=1
sysctl net.ipv4.tcp_max_tw_buckets=10000

В качестве альтернативы вы можете попробовать сокеты unix, чтобы узнать, помогает ли это.

Обзор сетевых сокетов Когда соединение устанавливается через TCP, сокет создается как на локальном, так и на удаленном хосте. Удаленный IP-адрес и порт принадлежат стороне сервера соединения и должны быть определены клиентом, прежде чем он сможет даже инициировать соединение. В большинстве случаев клиент автоматически выбирает, какой локальный IP-адрес использовать для соединения, но иногда его выбирает программное обеспечение, устанавливающее соединение. Наконец, локальный порт выбирается случайным образом из определенного диапазона, доступного операционной системе. Порт связан с клиентом только на время соединения, и поэтому называется эфемерным. Когда соединение прерывается, временный порт доступен для повторного использования.

Решение Включение соединений Keepalive

Используйте директиву keepalive для включения соединений keepalive от NGINX к вышестоящим серверам, определяя максимальное количество простаивающих соединений keepalive с вышестоящими серверами, которые сохраняются в кэше каждого рабочего процесса. При превышении этого числа самые последние использованные соединения закрываются. Без поддержки активности вы увеличиваете накладные расходы и неэффективны как с подключениями, так и с эфемерными портами.

http {
    upstream backend {
        server 10.0.0.100:1234;
        server 10.0.0.101:1234;
 }

    server {
        # ...
        location / {
            # ...
            proxy_pass http://backend;
            proxy_bind $split_ip;
            proxy_set_header X-Forwarded-For $remote_addr;
        }
    }

    split_clients "$remote_addr$remote_port" $split_ip {
        10%  10.0.0.210;
        10%  10.0.0.211;
        10%  10.0.0.212;
        10%  10.0.0.213;
        10%  10.0.0.214;
        10%  10.0.0.215;
        10%  10.0.0.216;
        10%  10.0.0.217;
        10%  10.0.0.218;
        *    10.0.0.219;
    }
}

Больше : https://www.nginx.com/blog/overcoming-ephemeral-port-exhauration-nginx-plus/