El número máximo de conexiones se ve afectado por ciertos límites tanto en el lado del cliente como del servidor, aunque de manera un poco diferente.
En el lado del cliente:
aumente el rango de puertos ephermal y disminuya eltcp_fin_timeout
Para conocer los valores predeterminados:
sysctl net.ipv4.ip_local_port_range
sysctl net.ipv4.tcp_fin_timeout
El rango de puertos ephermal define el número máximo de sockets salientes que un host puede crear desde una dirección IP particular. El fin_timeout
define el tiempo mínimo de estas tomas permanecerán en TIME_WAIT
estado (inutilizable después de ser utilizado una vez). Los valores predeterminados habituales del sistema son:
net.ipv4.ip_local_port_range = 32768 61000
net.ipv4.tcp_fin_timeout = 60
Esto básicamente significa que su sistema no puede garantizar consistentemente más de (61000 - 32768) / 60 = 470
sockets por segundo. Si no está satisfecho con eso, podría comenzar aumentando el port_range
. Establecer el rango en 15000 61000
es bastante común en estos días. Podría aumentar aún más la disponibilidad disminuyendo el fin_timeout
. Suponga que hace ambas cosas, debería ver más de 1500 conexiones salientes por segundo, más fácilmente.
Para cambiar los valores :
sysctl net.ipv4.ip_local_port_range="15000 61000"
sysctl net.ipv4.tcp_fin_timeout=30
Lo anterior no debe interpretarse como los factores que afectan la capacidad del sistema para realizar conexiones salientes por segundo. Pero más bien, estos factores afectan la capacidad del sistema para manejar conexiones concurrentes de manera sostenible durante grandes períodos de "actividad".
Los valores predeterminados de Sysctl en un cuadro típico de Linux para tcp_tw_recycle
y tcp_tw_reuse
serían
net.ipv4.tcp_tw_recycle=0
net.ipv4.tcp_tw_reuse=0
Estos no permiten una conexión desde un zócalo "usado" (en estado de espera) y obligan a los zócalos a durar el time_wait
ciclo completo . Recomiendo configurar:
sysctl net.ipv4.tcp_tw_recycle=1
sysctl net.ipv4.tcp_tw_reuse=1
Esto permite un ciclo rápido de los enchufes en time_wait
estado y su reutilización. Pero antes de hacer este cambio, asegúrese de que no entre en conflicto con los protocolos que usaría para la aplicación que necesita estos sockets. Asegúrese de leer la publicación "Enfrentando el TCP TIME-WAIT" de Vincent Bernat para comprender las implicaciones. La net.ipv4.tcp_tw_recycle
opción es bastante problemática para los servidores públicos, ya que no manejará las conexiones de dos computadoras diferentes detrás del mismo dispositivo NAT , lo cual es un problema difícil de detectar y espera para morderte. Tenga en cuenta que net.ipv4.tcp_tw_recycle
se ha eliminado de Linux 4.12.
En el lado del servidor:
el net.core.somaxconn
valor tiene un papel importante. Limita el número máximo de solicitudes en cola a un socket de escucha. Si está seguro de la capacidad de su aplicación de servidor, aumente el valor predeterminado de 128 a algo así como 128 a 1024. Ahora puede aprovechar este aumento modificando la variable de backlog de escucha en la llamada de escucha de su aplicación, a un número entero igual o superior.
sysctl net.core.somaxconn=1024
txqueuelen
El parámetro de sus tarjetas Ethernet también tiene un papel que desempeñar. Los valores predeterminados son 1000, por lo tanto, amplíelos hasta 5000 o incluso más si su sistema puede manejarlo.
ifconfig eth0 txqueuelen 5000
echo "/sbin/ifconfig eth0 txqueuelen 5000" >> /etc/rc.local
Del mismo modo aumentar los valores de net.core.netdev_max_backlog
y net.ipv4.tcp_max_syn_backlog
. Sus valores predeterminados son 1000 y 1024 respectivamente.
sysctl net.core.netdev_max_backlog=2000
sysctl net.ipv4.tcp_max_syn_backlog=2048
Ahora recuerde iniciar las aplicaciones del lado del cliente y del servidor aumentando los límites de FD en el shell.
Además de la técnica anterior más utilizada por los programadores, es reducir la cantidad de llamadas de escritura tcp . Mi preferencia es usar un búfer en el que inserto los datos que deseo enviar al cliente y luego, en los puntos apropiados, escribo los datos almacenados en el zócalo real. Esta técnica me permite usar grandes paquetes de datos, reducir la fragmentación, reduce la utilización de mi CPU tanto en el terreno del usuario como a nivel del núcleo.