Нужно увеличить пропускную способность nginx для восходящего сокета Unix - настройка ядра Linux?

28

Я использую сервер 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
Бен Ли
источник
Вы проверяли вывод ulimit, а именно количество открытых файлов?
Халед
@ Халед, ulimit -nговорит 65535.
Бен Ли

Ответы:

16

Похоже, узким местом является приложение, питающее сокет, а не само Nginx. Мы часто видим это с PHP при использовании сокетов по сравнению с TCP / IP-соединением. В нашем случае узкие места PHP гораздо раньше, чем Nginx.

Вы проверили превышение лимита отслеживания соединения sysctl.conf, лимита невыполнения сокетов

  • net.core.somaxconn
  • net.core.netdev_max_backlog
Бен Лессани - Сонасси
источник
2
Я понял проблему. Смотрите ответ, который я разместил. На самом деле это было узким местом приложения, а не сокетом, как вы и предполагали. Я исключил это ранее из-за неправильной диагностики, но оказалось, что проблема была в пропускной способности на другой сервер. Понял это всего пару часов назад. Я собираюсь наградить вас за вознаграждение, так как вы в значительной степени пригвоздили источник проблемы, даже несмотря на неверный диагноз, который я поставил в вопросе; однако, собираюсь поставить галочку в моем ответе, потому что мой ответ описывает точные обстоятельства, которые могут помочь кому-то в будущем с подобной проблемой.
Бен Ли
Получен новый сервер, перемещенный в местоположение, чтобы обеспечить достаточную пропускную способность, полностью перестроить систему и все еще иметь ту же проблему. Таким образом, оказывается, что моя проблема не решена в конце концов ... = (Я все еще думаю, что это зависит от приложения, но ничего не могу придумать. Этот новый сервер настроен точно так же, как другой сервер, где он работает нормально. Да, somaxconn и netdev_max_backlog записан правильно
Бен Ли
Ваша проблема не в nginx, она более чем способна, но это не значит, что у вас нет мошеннических настроек. Розетки особенно чувствительны при высокой нагрузке, когда границы не настроены правильно. Можете ли вы попробовать свое приложение вместо tcp / ip?
Бен Лессани - Сонасси
та же проблема с еще худшей величиной при использовании tcp / ip (очередь записи поднимается еще быстрее). У меня nginx / unicorn / kernel все настроено одинаково (насколько я могу судить) на другом компьютере, и на другом компьютере эта проблема не возникает. (Я могу переключать днс между двумя машинами, чтобы получить тестирование под нагрузкой, и иметь днс на 60-секундном интервале времени)
Бен Ли,
Пропускная способность между каждой машиной и машиной БД теперь одинакова, а задержка между новой машиной и машиной БД примерно на 30% больше, чем между старой машиной и БД. Но на 30% больше десятой доли миллисекунды - не проблема.
Бен Ли
2

Вы можете попробовать unix_dgram_qlenпосмотреть документацию к документам . Хотя это может усугубить проблему, указав больше в очереди? Вам придется посмотреть (netstat -x ...)

JMW
источник
Есть ли успехи в этом?
JMW
1
Спасибо за идею, но, похоже, это ничего не меняет.
Бен Ли
0

Я решил, увеличив число невыполненных заданий в 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
Адриан
источник
0

ТЛ; др

  1. Убедитесь, что резерв Unicorn большой (используйте сокет, быстрее, чем TCP) listen("/var/www/unicorn.sock", backlog: 1024)
  2. Оптимизировать настройки производительности NGINX , например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 не получает запросы для обработки, поэтому 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/*;
}
Epigene
источник