12 consejos para escalar Node.js

Node.js ya está operando con éxito a escala global, como lo demuestran las aplicaciones implementadas en él de compañías como Netflix, Reddit, Walmart y Ebay. Sin embargo, tiene su propio conjunto de problemas al escalar; desde el punto de vista de escalar personas que trabajan en una base de código único, por lo que desde el punto de vista del escalado vertical y horizontal en la nube. Además de mi experiencia personal con el escalado de Node.js para compañías como Reddit y Netflix, hablé con algunos expertos en Microsoft Azure y le ofrecí algunos consejos para escalar Node.js para su compañía.

Escribe un Node.js de calidad


Cuanto antes comience a usar linters, formateo y herramientas de verificación de tipo en su código, mejor.

Estas cosas pueden ser difíciles de introducir en el medio de un proyecto debido a la gran cantidad de refactorización que puede requerirse, también puede contaminar su historial de git, pero al final estas herramientas lo ayudarán a que el código sea legible.
Si todavía no los usa, vuelva inmediatamente a ESLint y Prettier . ESLint protegerá su código de patrones incorrectos, Prettier lo ayudará a formatear automáticamente su código antes de solicitarlo.

Una solución más sustancial es agregar herramientas como Flow o TypeScript a su base de código. Estas herramientas le permiten detectar errores más sutiles, como llamar a una función con un parámetro numérico en lugar de una cadena o llamar al método .filter en objetos en lugar de una matriz. A pesar de la complejidad y la necesidad de capacitar a su equipo, estas herramientas merecen su atención: pueden acelerar el desarrollo con Intellisense y prevenir errores de tiempo de ejecución con protección de tipo.

Escribir pruebas


Las pruebas siempre han sido un problema difícil para los desarrolladores. Algunos creen firmemente en el desarrollo basado en pruebas, mientras que otros rara vez escriben pruebas. Pero hay un término medio:

  • Defina módulos clave y escriba pruebas unitarias completas para ellos. Preste especial atención a los "viajes felices": casos extremos y escenarios en los que pueden ocurrir errores. Para otros módulos, escriba una o dos pruebas unitarias que cubran "caminos felices" y posiblemente casos comunes que haya descubierto
  • Prueba mínima de IU . La interfaz de usuario está cambiando constantemente y, a menudo, no es práctico pasar mucho tiempo haciendo pruebas para el código que cambiará con frecuencia.
  • Escribe pruebas para detectar errores . Siempre que encuentre y corrija un error en su código, escriba una prueba unitaria que detecte este error en el futuro.
  • Escriba algunas pruebas de integración para asegurarse de que todas las partes coincidan entre sí.
  • Escriba aún menos pruebas de extremo a extremo . Cubra las rutas clave en su sitio, por ejemplo, si está creando un sitio de comercio electrónico, puede valer la pena escribir una prueba para ingresar al sitio, agregarlo a la cesta y verificar la lista de productos. Estas pruebas son costosas de mantener, así que considere mantener un pequeño núcleo de pruebas que pueda motivar a mantener.

El punto de partida para escribir pruebas es la capacidad de implementar con confianza un nuevo código. Escriba tantas pruebas que no haya menos de lo que usted siente, pero trate de escribir no más que la lista anterior.

Diseño sin estado


La clave al escribir Node.js escalable es que sus servidores no tienen que almacenar estados para alguien o algo. Esto evitará la escala horizontal. Mueva el estado a otra aplicación y resuelva el problema en otro lugar (por ejemplo, Redis, Etcd, ...). Deberías pensar en esto de antemano. Entonces será muy difícil desentrañar si no ha hecho esto antes. También ayudará si alguna vez decide descomponer monolitos en microservicios.

Estadísticas: para desarrollo - Node.js, para producción - CDN


Cómo me gustaría que las empresas vean un error en este error. Servir sus activos estáticos desde su aplicación web (en particular a través de algo como webpack-dev-server o el servidor de desarrollo de Parsel) es una excelente experiencia de desarrollador, ya que acorta el ciclo de introducción al escribir código. Sin embargo, nunca debe publicar sus estadísticas a través de Node.js. Debe enviarse por separado a través de una CDN, como una CDN de Azure.

Los retornos estáticos con Node.js son innecesariamente lentos porque los CDN están más dispersos y, por lo tanto, físicamente más cerca del usuario final, y los servidores de CDN están altamente optimizados para pequeños recursos. Mantener las estadísticas con Node también es irrazonablemente costoso, ya que el tiempo del servidor Node.js es mucho más costoso que el tiempo del servidor CDN.

Comience a implementar temprano, implemente con más frecuencia


No te conozco, pero cuando desbloqueo algo por primera vez, nunca funciona. Esto generalmente se debe a que olvidé enviar las claves privadas correctas o codifiqué la ruta al host local. Pequeños problemas que funcionan localmente de forma remota se niegan a hacer esto. Estos problemas se pueden acumular, y lo que se podría solucionar fácilmente antes si, por supuesto, antes de encontrarlos, se puede convertir en una enorme cantidad de errores incomprensibles que simplemente no se pueden detectar normalmente.

Por cierto, Visual Studio Code te permite resolver este tipo de problema . Le permite implementar su aplicación directamente en Azure con un solo clic. Esta es una forma bastante simple de verificar que no haya problemas para implementar en otro entorno.

Implemente 2 servidores a la vez


Este consejo proviene de mi conocimiento ganado con esfuerzo y de un mar de dolor. La esencia del consejo es que hay pocas diferencias entre la implementación de dos servidores y diez servidores, y no hay mucha diferencia entre la implementación de diez servidores y cien servidores. Sin embargo, simplemente existe una gran diferencia entre implementar un servidor y dos servidores.
Similar al problema de implementar servidores sin estado, comenzando con dos servidores, puede superar rápidamente sus problemas de escala horizontal para que cuando haya un fuerte aumento en el tráfico, esté listo para escalar.

No tengas miedo de las líneas


Las bases de datos modernas manejan una cierta cantidad de lectura y escritura por su cuenta, sin su ayuda. Cuando esté probando su idea, no dude en confiar en su base de datos para manejar cargas de trabajo pequeñas o medianas.

La escala prematura tiene más probabilidades de matarte que salvarte. Pero, en algún momento, su aplicación crecerá y no podrá escribir todo en la base de datos también, ante problemas de ancho de banda de lectura y escritura. Para algunas aplicaciones que tienen un registro ligero, o si selecciona una base de datos como Cassandra, que maneja la escala masiva por sí sola, esto será un problema más adelante, para otros será más temprano.

Si tiene o tendrá un problema de este tipo, tendrá opciones para elegir tecnologías con las que irá más allá. Una de estas tecnologías puede ser la cola de mensajes. El estándar actual en este momento es Apache Kafka, que le permite organizar sus mensajes en temas y luego aplicaciones para suscribirse a este tema. Entonces, por ejemplo, puede acumular mensajes en la aplicación, escuchar un determinado tema y luego escribir datos por lotes en su base de datos para que no se obstruya todo el tiempo. Además, Kafka se ejecuta fácilmente en Azure .

Microservicios para escalar


A medida que su aplicación crece, comienzan a aparecer divisiones lógicas naturales. Una parte de la aplicación puede procesar pagos, mientras que la otra parte servirá la API para su interfaz. Al hacer divisiones lógicas, considere hacerlos microservicios separados. Pero tenga cuidado, ya que la introducción de microservicios también está cargada de gran complejidad. Pero vale la pena. Entonces, por ejemplo, cada microservicio puede tener su propia métrica. Al evaluarlos, puede escalarlos de forma independiente.

Use contenedores


Su aplicación puede funcionar bien localmente, pero puede haber serios problemas al intentar implementarla. Herramientas como Docker y Kubernetes funcionarán para evitar este problema. Docker, que puede imaginar como una mini instancia (contenedor) de Linux o Windows, en la que puede ejecutar la aplicación; y Kubernetes como una herramienta que conecta todos sus contenedores en la nube.

Kubernetes puede ser una bestia compleja, pero una bestia que resuelve un problema complejo. Si eres un hechicero DevOps inexperto, entonces puedes tener dificultades, por lo que te recomiendo comenzar con Draft . Si está familiarizado con Yeoman para proyectos Javascript, puede evaluar Draft como una herramienta similar, pero para proyectos Kubernetes: una herramienta que crea una estructura de alambre para su proyecto. A partir de ahí, puede usar la herramienta Helm para instalar piezas de arquitectura adicionales que necesita construir (por ejemplo, nginx, más servidores Node.js, MongoDB, Kafka, etc.), casi como npm para Kubernetes.

Tan pronto como comprenda el ecosistema de Kubernetes, a partir de ahora, la implementación en la nube se convertirá en un juego para niños.

Recoge métricas


Si no sabe cómo responder a la pregunta "¿Cómo funciona mi solicitud?", Entonces tendrá problemas o lo harán pronto. Después de todo, varios tipos de indicadores a lo largo del tiempo lo ayudarán a mejorar constantemente el estado de su aplicación. Desde el punto de vista de los costos para el futuro, y desde el punto de vista de la conveniencia del usuario en términos de mejorar el tiempo de respuesta. Definitivamente, debe realizar un seguimiento de las métricas, como las rutas lentas, las visitas a la página, el tiempo de sesión y otras métricas clave que son importantes para su negocio.

Hay muchas formas de recopilar estos indicadores. Servicios como New Relic y AppDynamics le proporcionarán información invaluable sobre cómo mejorar su aplicación.

Si trabaja con Azure, Application Insights también hace frente a esta necesidad, y también es fácil conectar otras herramientas como CI / CD.

CI / CD lo salvará de tanto dolor


¿Cuántas veces ha estropeado la implementación durante FTP y ha desactivado su servidor durante varios minutos? Fue conmigo. Nunca debe confiar en usted mismo para implementar el código de producción. Cómo hacer esto usando Visual Studio Code es bastante bueno, pero es principalmente para fines de desarrollo o demostración. Cuando esté listo para crear un sistema de nivel de producción, debe usar la integración continua y la implementación continua (a menudo abreviado CI / CD - integración continua y implementación continua).

La integración continua es la práctica del desarrollo de software, que consiste en fusionar copias de trabajo en una rama principal de desarrollo común varias veces al día y realizar ensamblajes automáticos frecuentes del proyecto para identificar rápidamente posibles defectos y resolver problemas de integración.

La implementación continua se encarga de tomar el código que pasó el elemento de configuración, ejecutar los pasos necesarios para compilarlos, empaquetarlos o empaquetarlos, y enviarlos al servidor. Es una buena práctica tener varios niveles para probar. Primero puede ir al servidor de desarrollo interno para verlo primero en un entorno de bajo riesgo. Puede probarlo primero antes de enviarlo a un entorno de control de calidad donde sus ingenieros de control de calidad o posiblemente un servicio externo confirmarán que todo funciona como se esperaba. A partir de ahí, puede cambiar a un entorno intermedio en el que su aplicación sigue siendo solo interna, pero funciona utilizando datos y configuraciones de producción, por lo que puede probarla en el entorno de producción antes de enviarla directamente a producción. También puede seleccionar un pequeño grupo de servidores para verificar el nuevo código: usted y dirigir solo un pequeño porcentaje del tráfico real a estos servidores para asegurarse de que nada se rompa cuando trabaje con usuarios reales. Si se rompe, ya sabe dónde buscar el problema. De lo contrario, puede pasar de un pequeño grupo de usuarios a todos.

Muchos proveedores y proyectos de código abierto abordan estas necesidades. Jenkins, Travis y CircleCI son excelentes opciones para CI. Azure tiene su propio servicio de CI / CD llamado Azure Pipelines, y es bastante intuitivo de usar, y nuevamente, se conecta fácilmente al ecosistema integrado de Azure.

Guardar secretos


Cualquier aplicación inevitablemente tiene algunos secretos. Pueden ser claves y líneas secretas de credenciales, bases de datos y mucho más. Sería muy malo si se convirtieran en las manos equivocadas. Sin embargo, son necesarios para ejecutar la aplicación. Entonces, ¿qué hacemos? Por lo general, en el desarrollo usaremos herramientas como dotenv para guardar el archivo de configuración localmente y poder leerlo a través de process.env en Node.js. Esto es genial para los desarrolladores, pero terrible para la producción.

En cambio, es útil usar algún tipo de herramienta de administración secreta. Afortunadamente, Kubernetes tiene un sistema incorporado y es bastante simple de usar. Proporciona secretos de Kubernetes en el lado del contenedor y luego los proporcionará a su aplicación como un entorno que complica enormemente el ataque.

Otra herramienta digna de su atención es Azure Key Vault . Lo bueno de Key Vault, aunque Microsoft no puede leer sus claves (solo usted tiene la opción de descifrarlas), Azure realizará un seguimiento de sus registros y de cualquier uso dudoso de sus claves para advertirle de cualquier compromiso.

Conclusión


Node.js, como cualquier otra plataforma, necesita ser escalado. Y, como cualquier otra plataforma, tiene sus propias tareas y la peculiaridad de escalar, que vale la pena conocer y que deben tenerse en cuenta al diseñar grandes proyectos.

Artículo original: "Once consejos para escalar Node.js" ( Es ).

Sugiero en los comentarios compartir consejos que puede dar sobre el escalado de Node.js. Será interesante escucharlo.

Source: https://habr.com/ru/post/es425275/


All Articles