Я запускаю сервер nginx, который действует как прокси для восходящего сокета unix, например:
upstream app_server {
server unix:/tmp/app.sock fail_timeout=0;
}
server {
listen ###.###.###.###;
server_name whatever.server;
root /web/root;
try_files $uri @app;
location @app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://app_server;
}
}
Некоторые процессы сервера приложений, в свою очередь, отключают запросы /tmp/app.sock
по мере их появления. Здесь используется конкретный сервер приложений - Unicorn, но я не думаю, что это имеет отношение к этому вопросу.
Проблема в том, что после определенной нагрузки nginx не может получать запросы через сокет с достаточно высокой скоростью. Неважно, сколько процессов сервера приложений я настроил.
Я получаю поток этих сообщений в журнале ошибок nginx:
connect() to unix:/tmp/app.sock failed (11: Resource temporarily unavailable) while connecting to upstream
Многие запросы приводят к коду состояния 502, а те, которые не требуют много времени для выполнения. Статистика очереди записи nginx колеблется около 1000.
В любом случае, я чувствую, что здесь не хватает чего-то очевидного, потому что эта конкретная конфигурация nginx и сервера приложений довольно распространена, особенно с Unicorn (на самом деле это рекомендуемый метод). Есть ли какие-либо параметры ядра Linux, которые нужно установить, или что-то в nginx? Есть идеи, как увеличить пропускную способность восходящего сокета? Что-то я явно делаю не так?
Дополнительная информация об окружающей среде:
$ uname -a
Linux servername 2.6.35-32-server #67-Ubuntu SMP Mon Mar 5 21:13:25 UTC 2012 x86_64 GNU/Linux
$ ruby -v
ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux]
$ unicorn -v
unicorn v4.3.1
$ nginx -V
nginx version: nginx/1.2.1
built by gcc 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
TLS SNI support enabled
Текущие настройки ядра:
net.core.rmem_default = 65536
net.core.wmem_default = 65536
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.tcp_mem = 16777216 16777216 16777216
net.ipv4.tcp_window_scaling = 1
net.ipv4.route.flush = 1
net.ipv4.tcp_no_metrics_save = 1
net.ipv4.tcp_moderate_rcvbuf = 1
net.core.somaxconn = 8192
net.netfilter.nf_conntrack_max = 524288
Настройки Ulimit для пользователя nginx:
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 20
file size (blocks, -f) unlimited
pending signals (-i) 16382
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 65535
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) unlimited
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
Похоже, что узким местом является приложение, питающее сокет, а не сам Nginx. Мы часто видим это с PHP, когда он используется с сокетами, а не с подключением TCP / IP. В нашем случае узкие места PHP возникли гораздо раньше, чем когда-либо делал Nginx.
Вы проверили лимит отслеживания соединений sysctl.conf, лимит невыполненных сокетов
net.core.somaxconn
net.core.netdev_max_backlog
Вы можете попробовать посмотреть на unix_dgram_qlen
, видеть документация по процессу. Хотя это может усугубить проблему, указав больше в очереди? Вам нужно будет посмотреть (netstat -x ...)
tl; dr
listen("/var/www/unicorn.sock", backlog: 1024)
worker_connections 10000;
Обсуждение
У нас была та же проблема - приложение Rails, обслуживаемое Unicorn за обратным прокси-сервером NGINX.
В журнале ошибок Nginx мы получали такие строки:
2019/01/29 15:54:37 [error] 3999#3999: *846 connect() to unix:/../unicorn.sock failed (11: Resource temporarily unavailable) while connecting to upstream, client: xx.xx.xx.xx, request: "GET / HTTP/1.1"
Читая другие ответы, мы также поняли, что, возможно, виноват Unicorn, поэтому мы увеличили его отставание, но это не решило проблему. Наблюдая за процессами сервера, было очевидно, что Unicorn не получает запросы для работы, поэтому NGINX оказался узким местом.
Поиск настроек NGINX для настройки nginx.conf
этот статья о настройке производительности указал на несколько параметров, которые могут повлиять на количество параллельных запросов, которые NGINX может обработать, в частности:
user www-data;
worker_processes auto;
pid /run/nginx.pid;
worker_rlimit_nofile 400000; # important
events {
worker_connections 10000; # important
use epoll; # important
multi_accept on; # important
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
keepalive_requests 100000; # important
server_names_hash_bucket_size 256;
include /etc/nginx/mime.types;
default_type application/octet-stream;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
gzip_disable "msie6";
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
Решил, увеличив число невыполненных заданий в config / unicorn.rb ... Раньше у меня отставание было 64.
listen "/path/tmp/sockets/manager_rails.sock", backlog: 64
и я получал эту ошибку:
2014/11/11 15:24:09 [error] 12113#0: *400 connect() to unix:/path/tmp/sockets/manager_rails.sock failed (11: Resource temporarily unavailable) while connecting to upstream, client: 192.168.101.39, server: , request: "GET /welcome HTTP/1.0", upstream: "http://unix:/path/tmp/sockets/manager_rails.sock:/welcome", host: "192.168.101.93:3000"
Теперь я увеличил до 1024 и не получаю ошибку:
listen "/path/tmp/sockets/manager_rails.sock", backlog: 1024
Значение backlog по умолчанию 1024 в конфигурации единорога.
http://unicorn.bogomips.org/Unicorn/Configurator.html
listen "/path/to/.unicorn.sock", :backlog => 1024
Клиент 1024 является ограничением сокета домена unix.