¿Necesita aumentar el rendimiento de nginx a un zócalo unix aguas arriba?

28

Estoy ejecutando un servidor nginx que actúa como un proxy para un socket ascendente de Unix, como este:

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;
        }
}

Algunos procesos del servidor de aplicaciones, a su vez, retiran las solicitudes a /tmp/app.sockmedida que están disponibles. El servidor de aplicaciones particular en uso aquí es Unicorn, pero no creo que sea relevante para esta pregunta.

El problema es que parece que después de una cierta cantidad de carga, nginx no puede recibir solicitudes a través del socket a una velocidad lo suficientemente rápida. No importa cuántos procesos del servidor de aplicaciones configure.

Recibo una avalancha de estos mensajes en el registro de errores de nginx:

connect() to unix:/tmp/app.sock failed (11: Resource temporarily unavailable) while connecting to upstream

Muchas solicitudes dan como resultado el código de estado 502, y las que no tardan mucho en completarse. La estadística de cola de escritura nginx ronda los 1000.

De todos modos, siento que me falta algo obvio aquí, porque esta configuración particular de nginx y el servidor de aplicaciones es bastante común, especialmente con Unicorn (de hecho, es el método recomendado). ¿Hay alguna opción de kernel de Linux que deba configurarse o algo en nginx? ¿Alguna idea sobre cómo aumentar el rendimiento al socket ascendente? ¿Algo que claramente estoy haciendo mal?

Información adicional sobre el medio ambiente:

$ 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

Ajustes actuales del kernel:

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

Configuración ilimitada para el usuario 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
Ben Lee
fuente
¿Verificó la salida de ulimit, específicamente el número de archivos abiertos?
Khaled
@Khaled, ulimit -ndice 65535.
Ben Lee

Respuestas:

16

Parece que el cuello de botella es la aplicación que alimenta el zócalo en lugar de ser Nginx. Esto lo vemos mucho con PHP cuando se usa con sockets versus una conexión TCP / IP. En nuestro caso, los cuellos de botella de PHP mucho antes de lo que lo haría Nginx.

¿Ha verificado el límite de seguimiento de conexión sysctl.conf, el límite de acumulación de socket

  • net.core.somaxconn
  • net.core.netdev_max_backlog
Ben Lessani - Sonassi
fuente
2
Resolví el problema. Vea la respuesta que publiqué. En realidad, fue el cuello de botella de la aplicación, no el zócalo, tal como lo postulas. Había descartado esto antes debido a un diagnóstico erróneo, pero resulta que el problema era el rendimiento a otro servidor. Lo descubrí hace solo un par de horas. Voy a otorgarle la recompensa, ya que prácticamente identificó la fuente del problema, incluso a pesar del diagnóstico erróneo que puse en la pregunta; sin embargo, le daré la marca de verificación a mi respuesta, porque mi respuesta describe las circunstancias exactas, por lo que podría ayudar a alguien en el futuro con un problema similar.
Ben Lee
Obtuve un nuevo servidor movido a una ubicación para proporcionar un rendimiento adecuado, reconstruyó completamente el sistema y aún tiene el mismo problema. Resulta que mi problema no está resuelto después de todo ... = (Todavía creo que es específico de la aplicación, pero no puedo pensar en nada. Este nuevo servidor está configurado exactamente como otro servidor donde funciona bien. Sí, somaxconn y netdev_max_backlog están correctamente subidas.
Ben Lee
Su problema no es nginx, es más que capaz, pero eso no quiere decir que no tenga una configuración no autorizada. Los zócalos son particularmente sensibles bajo alta carga cuando los límites no están configurados correctamente. ¿Puedes probar tu aplicación con tcp / ip?
Ben Lessani - Sonassi
mismo problema con una magnitud incluso peor usando tcp / ip (la cola de escritura sube aún más rápido). Tengo nginx / unicorn / kernel todo configurado exactamente igual (por lo que puedo decir) en una máquina diferente, y esa otra máquina no presenta este problema. (Puedo cambiar dns entre las dos máquinas, para obtener pruebas de carga en vivo y tener dns en un ttl de 60 segundos)
Ben Lee
El rendimiento entre cada máquina y una máquina de base de datos es el mismo ahora, y la latencia entre la nueva máquina y la máquina de base de datos es aproximadamente un 30% más que entre la máquina antigua y la base de datos. Pero un 30% más de una décima de milisegundo no es el problema.
Ben Lee
2

Puede intentar mirar unix_dgram_qlen, ver documentos de proceso . Aunque esto puede agravar el problema señalando más en la cola? Tendrás que mirar (netstat -x ...)

jmw
fuente
¿Algún progreso con esto?
jmw
1
Gracias por la idea, pero esto no pareció hacer ninguna diferencia.
Ben Lee
0

Lo resolví aumentando el número de pedidos pendientes en config / unicorn.rb ... Solía ​​tener un retraso de 64.

 listen "/path/tmp/sockets/manager_rails.sock", backlog: 64

y recibí este error:

 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"

Ahora, aumenté a 1024 y no obtengo el error:

 listen "/path/tmp/sockets/manager_rails.sock", backlog: 1024
Adrian
fuente
0

tl; dr

  1. Asegúrese de que la cartera de pedidos de Unicorn sea grande (use socket, más rápido que TCP) listen("/var/www/unicorn.sock", backlog: 1024)
  2. Optimizar la configuración de rendimiento de NGINX , por ejemploworker_connections 10000;

Discusión

Tuvimos el mismo problema: una aplicación Rails servida por Unicorn detrás de un proxy inverso NGINX.

Recibimos líneas como estas en el registro de errores de 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"

Al leer las otras respuestas, también nos dimos cuenta de que quizás Unicornio tiene la culpa, por lo que aumentamos su retraso, pero esto no resolvió el problema. Al monitorear los procesos del servidor, era obvio que Unicorn no estaba recibiendo las solicitudes para trabajar, por lo que NGINX parecía ser el cuello de botella.

La búsqueda de ajustes de NGINX para ajustar en nginx.confeste artículo de ajuste de rendimiento señaló varias configuraciones que podrían afectar la cantidad de solicitudes paralelas que NGINX puede procesar, especialmente:

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/*;
}
Epigenio
fuente