Los tiempos de espera de TCP vistos en la entrada anterior se pueden consultar y modificar en GNU/Linux a través de los ficheros apropiados del /proc y, para afinar un servidor y mejorar sus prestaciones en base a estos timeout, podremos modificar sus valores en este sistema de archivos sin necesidad de recompilar el núcleo. Pero, antes de nada, si lo que queremos es afinar nuestro sistema, lo que debemos es de plantearnos es esta pregunta: ¿cuántos puertos concurrentes podemos tener abiertos? Para ello:
- Debemos usar la información de /proc/sys/net/ipv4/ip_local_port_range. Por defecto contiene la línea: 32768 61000 que implica que podemos tener, en principio, 61000-32768 conexiones concurrentes.
- La de los tiempos de espera que veremos a continuación.
- Y la del número de descriptores de archivo que permite el sistema (los sockets también son descriptores en GNU/Linux): /proc/sys/fs/file-max
- Y todo esto dependiente de lo que me permita mi hardware 🙂
Como he escrito en el primer párrafo, los distintos tiempos de espera los podemos consultar y/o modificar en el /proc y, concretamente:
- Para el timeout de usuario tenemos que tiempo de espera estará marcado por el contenido del fichero /proc/sys/net/ipv4/tcp_keepalive_time. Transcurrido éste, mandaremos un máximo de /proc/sys/net/ipv4/tcp_keepalive_probes (por defecto 9) pruebas intercaladas en /proc/sys/net/ipv4/tcp_keepalive_intvl segundos (por defecto 75).
- Para el timeout de retransimisión, Linux dispone de /proc/sys/net/ipv4/retries1 y /proc/sys/net/ipv4/retries2 (se corresponden con R1 y R2 mencionados en la página 100 de la RFC 1122 ). El primero influye en el timeout tras el que TCP, si no recibe ACKs, decide que algo no va bien. En el segundo fichero encontramos un número que indicará el número de veces que tenemos que mandar un paquete antes de dar por finalizada una conexión (suponiendo que no se recibe la confirmación, por supuesto).
- /proc/sys/net/ipv4/tcp_fin_timeout nos permite ajustar el tiempo de espera (es decir, en ese fichero tenemos el valor de Maximum Segment Lifetime y por defecto es 60). Si queremos disponer del puerto inmediantamente, ¿qué tenemos que hacer? Pues activar (es decir, valor 1) en
- /proc/sys/net/ipv4/tcp_tw_recycle: Activado, permite la rápida reutilización de los sockets.
- /proc/sys/net/ipv4/tcp_tw_reuse: Activado, permite reutilizar los sockets para nuevas conexiones si es seguro desde el punto de vista del protocolo.
Para afinar el rendimiento de un servidor, podemos modificar los valores de varios ficheros:
- Incrementar /proc/sys/net/ipv4/ip_local_port_range El caso extremo sería que su contenido fuese: 1024 – 65535 Con esto lograríamos incrementar el número de puertos concurrentes. Pero cuidado. Nuestro sistema debe ser capaz de proporcionarles recursos. Aquí no podemos aplicar lo de cuanto más azúcar, más dulce.
- Permitir la reutilización inmediata de los puertos: /proc/sys/net/ipv4/tcp_tw_reuse a 1. Conseguimos liberar recursos cuanto antes y ponerlos disponibles para otras tareas.
- Reducir el valor de MSL /proc/sys/net/ipv4/tcp_fin_timeout a 15 o 30 segundos. En las redes de hoy en día, tampoco debemos tener excesivos timeouts; aunque si hacemos lo del punto 2, este punto pierde interés.
- Reducir el número de pruebas en el timeout de usuario. Por ejemplo, en redes fiables, quizás un valor de 3 para /proc/sys/net/ipv4/tcp_keepalive_probes pueda ser bueno ya que si fallan, es bastante probable que sea bueno dar por cerrada la conexión.
A veces, algunos expertos, recomiendan activar /proc/sys/net/ipv4/tcp_tw_recycle, pero esta opción puede crearnos problemas con:
- conexiones NAT (opción muy utilizada por los routers, en la Universidad de Alicante, por ejemplo, lo hacemos).
- balanceadores de carga de red (en EPSAlicante, para ciertos servicios, también usamos esta opción).
Al igual que en http://linux.die.net/man/7/tcp, recomiendo mantenerlo desactivado.