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:
- ¿Cuál debería ser el valor óptimo o recomendado para esto?
- ¿Cuáles son las desventajas de usar una gran cantidad de conexiones de trabajadores?
Respuestas:
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:
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:
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.
fuente
sendfile
) para poder multiplicar a calcular cuánta RAM se necesitaría para mantener un número determinado deworker_connections
.sysctl
configuración.ulimit -a
le dirá cuántos archivos abiertos su sistema permite que use un proceso.Además,
net.ipv4.ip_local_port_range
establece el rango total de sockets para habilitar por IP.Por lo tanto,
worker_connections
no 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_timeout
y 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 utilizandosysctl
, 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!
fuente
net.ipv4.ip_local_port_range
solo 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í .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
fuente
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:
Y puede ser confirmada a nivel de código fuente en
event/ngx_event.c
, tambiénfuente
¡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.
fuente
max_connections
es más alto que el límite flexible predeterminado.