Valor óptimo para Nginx trabajador_conexiones

25

Nginx worker_connections"establece el número máximo de conexiones simultáneas que puede abrir un proceso de trabajo. Este número incluye todas las conexiones (por ejemplo, conexiones con servidores proxy, entre otros), no solo conexiones con clientes. Otra consideración es que el número real de conexiones simultáneas no puede exceder el límite actual en el número máximo de archivos abiertos ". Tengo pocas consultas sobre esto:

  1. ¿Cuál debería ser el valor óptimo o recomendado para esto?
  2. ¿Cuáles son las desventajas de usar una gran cantidad de conexiones de trabajadores?
Aarti
fuente
+1, buena pregunta!
cnst

Respuestas:

31

Tomemos el enfoque pragmático.

Todos estos límites son cosas que fueron codificadas y diseñadas en el siglo pasado cuando el hardware era lento y costoso. Estamos en 2016 ahora, un tostador de pared promedio puede procesar más solicitudes que los valores predeterminados.

La configuración predeterminada es realmente peligrosa. Tener cientos de usuarios en un sitio web no es nada impresionante.

proceso_trabajador

Una configuración relacionada, expliquemos mientras estamos en el tema.

nginx como balanceador de carga:

  • 1 trabajador para el equilibrio de carga HTTP.
  • 1 trabajador por núcleo para el equilibrio de carga HTTPS.

nginx como servidores web:

Este es complicado.

Algunas aplicaciones / frameworks / middleware (por ejemplo, php-fpm) se ejecutan fuera de nginx. En ese caso, 1 nginx worker es suficiente porque generalmente es la aplicación externa la que está haciendo el procesamiento pesado y consumiendo los recursos.

Además, algunas aplicaciones / frameworks / middleware solo pueden procesar una solicitud a la vez y es contraproducente sobrecargarlas.

En términos generales, 1 trabajador es siempre una apuesta segura.

De lo contrario, puede poner un trabajador por núcleo si sabe lo que está haciendo. Consideraría que la ruta es una optimización y recomendaría una evaluación comparativa y pruebas adecuadas.

conexiones_ trabajador

La cantidad total de conexiones es worker_process * worker_connections . La mitad en modo equilibrador de carga.

Ahora estamos llegando a la parte de la tostadora. Hay muchos límites del sistema seriamente subestimados:

  • ulimits es 1k máximo de archivos abiertos por proceso en Linux (1k suave, 4k duro en alguna distribución)
  • Los límites de systemd son casi lo mismo que ulimits.
  • El valor predeterminado de nginx es 512 conexiones por trabajador.
  • Puede haber más: SELinux, sysctl, supervisor (cada versión de distro + es ligeramente diferente)

1k trabajador_conexiones

El valor predeterminado seguro es poner 1k en todas partes.

Es lo suficientemente alto como para ser más de lo que la mayoría de los sitios internos y desconocidos encontrarán. Es lo suficientemente bajo como para no alcanzar ningún otro límite del sistema.

10k trabajador_conexiones

Es muy común tener miles de clientes, especialmente para un sitio web público. Dejé de contar la cantidad de sitios web que he visto que cayeron debido a los bajos valores predeterminados.

El mínimo aceptable para la producción es de 10k. Los límites relacionados del sistema deben aumentarse para permitirlo.

No existe un límite demasiado alto (un límite simplemente no tiene efecto si no hay usuarios). Sin embargo, un límite demasiado bajo es algo muy real que resulta en usuarios rechazados y un sitio muerto.

Más de 10k

10k es agradable y fácil.

Podríamos establecer límites arbitrarios de 1000kk (es solo un límite después de todo) pero eso no tiene mucho sentido práctico, nunca obtenemos ese tráfico y no podríamos tomarlo de todos modos.

Sigamos con 10k como una configuración razonable. Los servicios que están buscando (y realmente pueden hacer) más requerirán ajustes y evaluaciones comparativas especiales.

Escenario especial: uso avanzado

A veces, sabemos que el servidor no tiene muchos recursos y esperamos picos sobre los que no podemos hacer mucho. Preferimos rechazar a los usuarios que intentarlo. En ese caso, establezca un límite de conexión razonable y configure buenos mensajes de error y manejo.

A veces, los servidores de back-end funcionan bien y bien, pero solo hasta un poco de carga , algo más y todo se va rápidamente. Preferimos reducir la velocidad que tener los servidores bloqueados. En ese caso, configure la cola con límites estrictos, deje que nginx amortigüe todo el calor mientras las solicitudes se agotan a un ritmo limitado.

usuario5994461
fuente
Me gusta la respuesta, pero para hacer una suposición verdaderamente educada sobre qué tan alto se debe establecer eso, parece que tendríamos que saber aproximadamente cuánta RAM se necesita una conexión (por ejemplo, para guardar un archivo estático normal sendfile) para poder multiplicar a calcular cuánta RAM se necesitaría para mantener un número determinado de worker_connections.
nh2
1
Puede hacer hasta 10k sin demasiados ajustes. Los búferes de conexión se establecen en la sysctlconfiguración.
user5994461
10

ulimit -a le dirá cuántos archivos abiertos su sistema permite que use un proceso.

Además, net.ipv4.ip_local_port_rangeestablece el rango total de sockets para habilitar por IP.

Por lo tanto, worker_connectionsno puede ser más que cualquiera de ellos, o las conexiones de su cliente se pondrán en colanet.core.netdev_max_backlog el tamaño total de la cola TCP.

Tenga en cuenta que si usa nginx como proxy inverso, usa dos sockets por conexión. Es posible que desee jugar un poco con net.ipv4.tcp_fin_timeouty otros tiempos de espera relacionados con el kernel tcp para intentar cambiar el estado de los sockets rápidamente. Otra cosa a tener en cuenta es que cada socket asigna memoria de la pila de memoria TCP, también puede establecer algunos límites de la pila de memoria TCP utilizando sysctl, puede ejercer más presión en la RAM siempre que tenga CPU y suficientes controladores de archivos.

Para su información, es posible con suficientes recursos informáticos, tener un servidor con alrededor de 32 GB de RAM y algunas interfaces de red virtuales para manejar conexiones simultáneas de 1MM con algunos ajustes de kernel utilizando sysctl. Durante mis pruebas al tratar con más de 1MM y enviar una carga útil de alrededor de 700Bytes, el servidor tardó alrededor de 10 segundos en actualizar aproximadamente 1.2MM clientes simultáneos. Lo siguiente fue aumentar el ancho de banda de la red al vincular algunas NIC adicionales y deshacerse de las unidades virtuales. Es posible lograr una comunicación pseudo casi en tiempo real con más de 1.2MM clientes, dada la carga útil, el ancho de banda y el tiempo razonable para actualizar a todos los clientes.

Feliz afinación!

Marcel
fuente
por favor arregle el comando para ulimit no ulimits
Ali.MD
Note net.ipv4.ip_local_port_rangesolo es relevante para conexiones salientes , no para conexiones entrantes (como es típico con nginx en, por ejemplo, los puertos 80 y 443); ver aquí .
nh2
@ nh2 pero si uno usa nginx como proxy inverso, hay al menos 2 sockets abiertos por conexión de cliente, y luego importa a cuántos puertos locales el núcleo puede permitir que se unan los sockets.
Marcel
Si eso es correcto.
nh2
0

El tamaño apropiado se puede descubrir mediante pruebas, ya que es variable según el tipo de tráfico que maneja Nginx.

Teóricamente, nginx puede manejar: clientes máximos = procesos_trabajadores * conexiones_trabajadores (* = multiplicar) y procesos_trabajadores = número de procesadores

Para encontrar procesadores, use: procesador grep / proc / cpuinfo | wc -l

Sachin Gargya
fuente
En realidad, con el proxy inverso: max_clients = (trabajador_procesos * trabajador_conexiones) / (X * 2) donde X es la cantidad de conexiones simultáneas que estos clientes le hacen. Además, las estructuras de conexión se utilizan para enchufes de escucha, enchufes de control interno entre procesos nginx y para conexiones ascendentes. Por lo tanto, este número máximo de clientes = trabajador_procesos * trabajador_conexiones no funcionará, ya que no sabemos que se estén utilizando muchas conexiones en los sockets de control interno.
Aarti
0

Establecer límites inferiores puede ser útil cuando puede tener recursos limitados. Algunas conexiones, por ejemplo, conexiones de mantenimiento (no solo con los clientes, sino también con los servidores ascendentes) ), están desperdiciando efectivamente sus recursos (incluso si nginx es muy eficiente, lo que es), y no son necesarios para El funcionamiento correcto de un servidor de uso general, lo que significa que se pueden eliminar de forma segura para que haya más recursos disponibles para el resto de la operación.

Por lo tanto, tener un límite de recursos más bajo indicaría a nginx que puede tener pocos recursos físicos, y los disponibles deben asignarse a nuevas conexiones, en lugar de servir a las conexiones inactivas de mantenimiento a costa de las conexiones más nuevas que tienen problemas para atender las necesidades más urgentes.

¿Cuál es el valor recomendado? Es lo predeterminado.

Todos los valores predeterminados están documentados en la documentación:

Valor predeterminado: trabajador_conexiones 512;

Y puede ser confirmada a nivel de código fuente enevent/ngx_event.c , también

13 # define DEFAULT_CONNECTIONS 512

cnst
fuente
0

¡La respuesta de Marcel realmente necesita ser votada! Si ulimits se establece en un valor predeterminado de alrededor de 1k, max_ connections debe establecerse alrededor del mismo valor; de lo contrario, no hay ningún beneficio en establecer max_ connections en 10k.

Recibirá solicitudes en cola y sockets cerrados en nginx si "sus conexiones de trabajo no pueden ser más que ninguno de esos, o sus conexiones de cliente se pondrán en cola hasta net.core.netdev_max_backlog, el tamaño total de la cola TCP".

Se puede abrir un único proceso, así como la conexión, según lo permitan las ulimits. num_workers * max_ connections es la fórmula, pero fuera de las conexiones maxim del equilibrador de carga / proxy y ulimits deben tenerse en cuenta para valores razonables. Establecer max_connection en un valor realmente alto puede ser contraproducente ya que ulimits será un factor limitante.

Criptofobia
fuente
1
Eso está realmente mal. El límite flexible en Linux de escritorio es 1k, pero no impide que los procesos utilicen más que eso si así lo solicitan, hasta el límite rígido (32k o más). nginx aumentará el ulimit automáticamente si max_connectionses más alto que el límite flexible predeterminado.
user5994461