Análisis de conexiones TIME_WAIT


El tema de las conexiones mal utilizadas es un dolor de cabeza para muchos administradores de servidores de aplicaciones. Es común que las aplicaciones que mantenemos en nuestro resguardo sufran degradación, e incluso fallos, por el "simple" hecho de no cerrar las conexiones o tardar demasiado en hacerlo (vía sistema operativo). Como sabemos, una conexión pasa por varios estados, mismos que salen de la intención de este escrito.



Las conexiones establecidas (ESTABLISHED) son demasiado costosas cuando abren y cierran, debido a eso, se han creado manejadores de conexiones (pooles) que mantienen abiertas las conexiones para reutilizarlas dependiendo la demanda. Es por eso, que en medida de lo posible, hay que utilizar un manejador de conexiones, ya sea a base de datos o algún broker.

Entrando de lleno al tema, las conexiones en estado TIME_WAIT son un problema por el consumo de memoria, ocupando cada una 64k de memoria no paginable, es decir,  todo el tiempo se mantienen en memoria RAM. La intención de este escrito es dar un bosquejo de lo importante que es administrar las conexiones de una manera prolija, y para ello debemos aprender a visualizar de dónde viene el problema.

Las conexiones en TIME_WAIT no tienen un proceso dueño, eso las hace más complicadas de rastrear, y ahí es donde el instinto sabueso se vuelve imprescindible. Por lo normal, dependiendo el punto de llegada, podemos conocer (son limitados) los procesos o servicios que se conectan a dicho puerto. Formulamos una teoría y observamos. Para ello, se pueden construir pequeños scripts como el que más adelante muestro.

¿Por qué son malignas las conexiones en TIME_WAIT?

Vamos a decir que tenemos 1000 conexiones en TIME_WAIT, si hacemos las multiplicaciones debidas, resulta lo siguiente:


1000 x 64 =64000kb
64000/1024=62.5mb


Como tip, las conexiones de esta naturaleza no se pueden observar en los servidores, ya que el estado TIME_WAIT es exclusivo del cliente, porque "está esperando los paquetes en la red que aún no han llegado". 

El manual de netstat nos dice lo siguiente:

     TIME_WAIT:  The socket connection has been closed by the local
     application, the remote peer has closed its half of the connection, and
     the system is waiting to be sure that the remote peer received the last
     acknowledgement.




Es hora de monitorear



Bash es una herramienta muy poderosa y versátil. Su flexibilidad está en cómo y qué vamos aprendiendo, para después conjugarlo con otros saberes y así potenciarlo. Lo primero que tenemos que indagar es qué conexiones, cada cuánto se generan, y el tiempo que tardan en morir. Para ello, tenemos que armarnos de mucha paciencia y una serie de comandos que sean fiables. 

Elaboré el siguiente bash script para tal tarea. El mismo corre en entornos que tengan GNU/Linux y MacOS. Lo pueden ejecutar en medio de un while infinito, con espacios de tiempo entre 2 y 5 segundos, para no saturar al servidor (en especial si hay muchas conexiones) y no perder el detalle de la observación.

netstat -na | awk '/tcp/ {print $6}' |sort | uniq -c




También podemos hacer un monitoreo más específico, yendo por puerto (o puertos):

netstat -na | grep '.443' |awk '/tcp/ {print $6}'

En el siguiente ejemplo, hacemos un conteo de las conexiones que tenemos al puerto 443.

 netstat -na | grep '.443' |awk '/tcp/ {print $6}' | sort | uniq -c

Ahora, cuando se detecta demasiadas conexiones en TIME_WAIT es necesario saber qué tiempo tardan en ese estado, para ello podemos valernos de una bandera del mismo comando netstat (solo funciona en GNU/ Linux):

netstat -nao | grep TIME_WAIT | grep '443' | head

Los primeros dos dígitos están dados en segundos. Si ejecutamos recurrentemente el comando anterior y filtramos por el identificador único de la conexión, podremos observar el tiempo que tarda en cerrarse. En las plataformas GNU/ Linux por lo normal tarda 2 minutos en hacerlo, para ello, se pueden acortar los tiempos de vida de las conexiones tcp vía parámetros de kernel. Lo ideal es que el problema se solucione desde el proceso (aplicación) que está abriendo esas conexiones, ¿Es en verdad necesario que abra tantas conexiones?

Lo siguiente que podemos hacer es paliar, un poco, a través del establecimiento de nuevos parámetros del sistema operativo. Quizá ese tema lo aborde en otro escrito, ya que volvería demasiado extenso el actual.

Espero que les sea de ayuda para iniciar el complejo mundo de la administración de los servidores de aplicaciones.

Comentarios

Entradas populares de este blog

Agregar un usuario a un grupo secundario

Pluging de HAProxy para Collectd.