Я проводил нагрузочное тестирование с 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/