¿Por qué mi servidor web está cayendo las conexiones con un restablecimiento TCP a alta carga?

10

Tengo una pequeña configuración de VPS con nginx. Quiero exprimir el máximo rendimiento posible, así que he estado experimentando con la optimización y las pruebas de carga.

Estoy usando Blitz.io para hacer pruebas de carga al OBTENER un pequeño archivo de texto estático, y me encuentro con un problema extraño en el que el servidor parece estar enviando restablecimientos de TCP una vez que el número de conexiones simultáneas alcanza aproximadamente 2000. Sé que esto es muy gran cantidad, pero al usar htop, el servidor todavía tiene mucho de sobra en tiempo de CPU y memoria, por lo que me gustaría averiguar la fuente de este problema para ver si puedo impulsarlo aún más.

Estoy ejecutando Ubuntu 14.04 LTS (64 bits) en un VPS Linode de 2GB.

No tengo suficiente reputación para publicar este gráfico directamente, así que aquí hay un enlace al gráfico Blitz.io:

ingrese la descripción de la imagen aquí

Aquí hay cosas que he hecho para tratar de descubrir la fuente del problema:

  • El valor de configuración de nginx worker_rlimit_nofilese establece en 8192
  • se ha nofileestablecido en 64000 para los límites de hardware y software para rooty para el www-datausuario (como se ejecuta nginx) en/etc/security/limits.conf
  • no hay indicios de que algo vaya mal /var/log/nginx.d/error.log(por lo general, si se encuentra con límites de descriptor de archivo, nginx imprimirá mensajes de error que lo indiquen )

  • Tengo ufw setup, pero no hay reglas de limitación de velocidad. El registro de ufw indica que no se está bloqueando nada y he intentado deshabilitar ufw con el mismo resultado.

  • No hay errores indicativos en /var/log/kern.log
  • No hay errores indicativos en /var/log/syslog
  • He agregado los siguientes valores /etc/sysctl.confy los he cargado sysctl -psin ningún efecto:

    net.ipv4.tcp_max_syn_backlog = 1024
    net.core.somaxconn = 1024
    net.core.netdev_max_backlog = 2000
    

¿Algunas ideas?

EDITAR: Hice una nueva prueba, aumentando a 3000 conexiones en un archivo muy pequeño (solo 3 bytes). Aquí está el gráfico Blitz.io:

Gráfico Blitz.io

De nuevo, según Blitz, todos estos errores son errores de "restablecimiento de la conexión TCP".

Aquí está el gráfico de ancho de banda de Linode. Tenga en cuenta que este es un promedio de 5 minutos, por lo que es un filtro de paso bajo (el ancho de banda instantáneo es probablemente mucho más alto), pero aún así, esto no es nada:

ingrese la descripción de la imagen aquí

UPC:

ingrese la descripción de la imagen aquí

E / S:

ingrese la descripción de la imagen aquí

Aquí está htopcerca del final de la prueba: htop

También capturé parte del tráfico usando tcpdump en una prueba diferente (pero de aspecto similar), comenzando la captura cuando comenzaron a aparecer los errores: sudo tcpdump -nSi eth0 -w /tmp/loadtest.pcap -s0 port 80

Aquí está el archivo si alguien quiere echarle un vistazo (~ 20MB): https://drive.google.com/file/d/0B1NXWZBKQN6ETmg2SEFOZUsxV28/view?usp=sharing

Aquí hay un gráfico de ancho de banda de Wireshark:

ingrese la descripción de la imagen aquí (La línea es todos los paquetes, las barras azules son errores de TCP)

Según mi interpretación de la captura (y no soy un experto), parece que los indicadores TCP RST provienen de la fuente de prueba de carga, no del servidor. Entonces, suponiendo que algo no está mal del lado del servicio de prueba de carga, ¿es seguro asumir que esto es el resultado de algún tipo de gestión de red o mitigación de DDOS entre el servicio de prueba de carga y mi servidor?

¡Gracias!

Erik Swan
fuente
¿Su proveedor está haciendo algún tipo de mitigación de DDoS? Esto puede interferir con su prueba.
Michael Hampton
@MichaelHampton Estoy bastante seguro de que Linode no hace eso.
EEAA
¿Puedes publicar el gráfico de red desde el panel de control de Linode? ¿Cuánto ancho de banda ocupa realmente esta prueba?
EEAA
Investigué un poco más y actualicé la publicación original con mucha más información. También confirmó con Linode que no hacen la mitigación de DDOS, aunque esto no significa necesariamente que un proveedor de red entre el servicio de prueba de carga y Linode no esté haciendo nada. ¡Gracias!
Erik Swan
1
¿Hay alguna razón por la que solo configuró net.core.netdev_max_backloghasta 2000? Varios ejemplos que he visto tienen un orden de magnitud mayor para conexiones gigabit (y 10Gig).
Moshe Katz

Respuestas:

1

Podría haber cualquier número de fuentes de restablecimiento de la conexión. El probador de carga podría estar fuera de los puertos efímeros disponibles desde los cuales iniciar una conexión, un dispositivo en el camino (como un firewall que hace NAT) podría tener su grupo NAT agotado y no puede proporcionar un puerto de origen para la conexión. ¿un equilibrador de carga o firewall en su extremo que podría haber alcanzado un límite de conexión? Y si se hace NAT de origen en el tráfico entrante, eso también podría experimentar agotamiento de puertos.

Uno realmente necesitaría un archivo pcap de ambos extremos. Lo que desea buscar es si se envía un intento de conexión pero nunca llega al servidor, pero todavía aparece como si el servidor lo restableciera. Si ese es el caso, entonces algo en la línea tuvo que restablecer la conexión. El agotamiento de la agrupación NAT es una fuente común de este tipo de problemas.

Además, netstat -st podría brindarle información adicional.

GeorgeB
fuente
1

Algunas ideas para probar, basadas en mis propias experiencias de afinación similares recientes. Con referencias:

Dices que es un archivo de texto estático. En caso de que haya algún procesamiento ascendente en curso, aparentemente los sockets de dominio mejoran el rendimiento de TCP a través de una conexión basada en un puerto TC:

https://rtcamp.com/tutorials/php/fpm-sysctl-tweaking/ https://engineering.gosquared.com/optimising-nginx-node-js-and-networking-for-heavy-workloads

Independientemente de la terminación aguas arriba:

Habilite multi_accept y tcp_nodelay: http://tweaked.io/guide/nginx/

Deshabilite el inicio lento de TCP: /programming/17015611/disable-tcp-slow-start http://www.cdnplanet.com/blog/tune-tcp-initcwnd-for-optimum-performance/

Optimizar la ventana de congestión TCP (initcwnd): http://www.nateware.com/linux-network-tuning-for-2013.html

JayMcTee
fuente
1

Para establecer el número máximo de archivos abiertos (si eso está causando su problema) necesita agregar "fs.file-max = 64000" a /etc/sysctl.conf

Sean1e
fuente
0

Por favor, mire cuántos puertos están en TIME_WAITestado usando el comando netstat -patunl| grep TIME | wc -ly cambie net.ipv4.tcp_tw_reusea 1.

fgbreel
fuente
¿Cómo vería cuántos puertos hay en el TIME_WAITestado?
Erik Swan el
Usando netstato ss. ¡Actualicé mi respuesta con el comando completo!
fgbreel
He vuelto a ejecutar la prueba y watch -n 1 'sudo netstat -patunl | grep TIME | wc -l'devuelve 0 a lo largo de toda la prueba. Estoy seguro de que los reinicios se producirán como resultado de la mitigación de DDOS por parte de alguien entre el probador de carga y mi servidor, según mi análisis del archivo PCAP que publiqué anteriormente, ¡pero si alguien pudiera confirmarlo, sería genial!
Erik Swan