Como podemos ver, DevTools y el mecanismo de instantáneas de heap de memoria es una gran manera de encontrar y solucionar fugas de memoria y de esta manera resolver los problemas de CPU y memoria. Pero, ¿es la única manera? Pero primero que todo, hablemos de los beneficios y limitaciones de este enfoque. Los beneficios son que es muy fácil de usar en el ciclo de desarrollo. Hay múltiples herramientas de desarrollo que puedo usar. Puedo usarlo con los Chrome DevTools. Puedo usarlo con los DevTools que están integrados, por ejemplo, en VS Code. También puedo perfilar una fuga durante el inicio usando Inspect BRK en lugar de Inspect. Pero también hay desventajas en este enfoque. Requiere un reinicio para agregar ese flag de CLI que pone el node en modo de desarrollo. Requiere acceso desde el entorno de desarrollo a la instancia de node usando el protocolo de depuración de Chrome, lo cual es un problema de seguridad aunque puedes tunelarlo sobre SSH. Obviamente hay una sobrecarga de rendimiento al ejecutar la instancia de node en modo de depuración, y también puedo romper accidentalmente el servicio simplemente presionando el botón de pausa en el entorno de desarrollo. Además, tomar instantáneas es realmente pesado, y si no tengo cuidado, puedo realmente matar el proceso solo tomando una instantánea de memoria.
Otra manera interesante de obtener una instantánea es usar un nuevo flag experimental de node, heap snapshot near heap limit, y especificas cuántas instantáneas de heap tomar. Entonces, lo que sucede es que cuando node se acerca al límite de memoria del heap, tomará una instantánea hasta tres veces en este caso, para que aún pueda hacer la diferencia y encontrar la razón de lo que realmente está filtrando al hacer la comparación entre las instantáneas. Esta es una manera interesante, pero necesitas tener cuidado con ella porque, nuevamente, tomar esa instantánea podría simplemente llevarte más allá del límite y causar que el proceso se bloquee. En realidad, prefiero otra manera, que es especificar que node tomará una instantánea automáticamente cuando reciba una señal. Así que en este caso, uso el node snapshot signal equals siguser2, y luego si uso el comando kill de linux para enviar esa señal a ese proceso, realmente haré que genere un archivo de volcado de heap en una carpeta especificada. ¿Cuáles son los beneficios de este enfoque? Primero que todo, es configurar y olvidar. Puedes ponerlo en producción siempre que no estés tomando instantáneas. No hay sobrecarga, y es seguro porque no necesito abrir un puerto de depuración a esa instancia. En el lado negativo, necesito poder acceder a esa caja de Linux, por ejemplo, usando SSH para enviar la señal a ese proceso. Además, los volcados en sí mismos ocupan espacio en el servidor, y necesitas tener cuidado con cuántos volcados realmente pones allí antes de limpiar para asegurarte de que no explotes tu disco. Y, nuevamente, tomar la instantánea, sigue siendo una operación pesada y puede llevarte más allá del límite.
La tercera manera es realmente usar una API. Hay APIs integradas en Node que puedes usar para generar volcados de heap. Así que puedes implementar, por ejemplo, tu propio endpoint TCP que escuche algún tipo de instrucción y genere un volcado de heap bajo demanda y lo coloque donde quieras que vaya. Obviamente, eso requiere un poco más de esfuerzo. Los beneficios de usar una API, puedes controlar exactamente cuándo y cómo invocarla. Y, nuevamente, no hay sobrecarga cuando está inactiva. Solo hay sobrecarga cuando realmente invocas ese endpoint.
Comments