Cómo seleccionar una plataforma de desarrollo para un proyecto web II

Este artículo es una actualización de otro anterior publicado en 2013 sobre Java/Tomcat, PHP/Zend, Python/Django y C#/IIS.

Desde 2013 dos plataformas, Play y Node.js, han aumentado con fuerza su popularidad entre los desarrolladores debido a las siguientes tendencias en el diseño de aplicaciones web.

1ª) Crecimiento de la base de usuarios de los lenguajes base. JavaScript en el caso de Node.js y Scala en el caso de Play. Sumado a una tendencia generalizada hacia un estilo de programación más funcional.

2ª) Obsesión por las llamadas no bloqueantes. El “problema” de diseño de la mayoría de los servidores web es que usan un hilo de ejecución (thread) por conexión. Esto en la práctica limita el número de conexiones concurrentes por máquina a algo entre 200 y 400 antes de que la sobrecarga debida al cambio de contexto entre hilos empiece a perjudicar el rendimiento del servidor. El maximizar la cantidad de conexiones concurrentes sin degradar el rendimiento siempre ha sido un desafío técnico en los sitios web pero la necesidad se ha vuelto mucho más acuciante desde que se pusieron de moda las páginas web que cargan contenidos dinámicamente de forma constante mediante llamadas AJAX o requieren de actualizaciones frecuentes de datos desde el servidor. En Java, desde la especificación de servlets versión 3.0 (creo) es posible crear servlets asíncronos pero es bastante complicado. Además, JDBC es un API síncrono lo cual dificulta el desarrollo de servlets asíncronos.

3ª) Renderizado en el cliente. Otra moda encabezada por toolkits como Angular JS y React JS es pedir datos en formato JSON al servidor y renderizar la página en el cliente mediante JavaScript en lugar de pedir una página ya renderizada. Si bien se puede argüir que trasladar el trabajo de renderización al cliente reduce la carga en el servidor, yo personalmente estoy en contra de hacer sitios web que sólo muestren algo decente si JavaScript está activado en el navegador. Para renderizar en el cliente la verdad es que no entiendo muy bien por qué los fabricantes de navegadores nunca soportaron XSLT decentemente. Supongo que XSLT es simplemente demasiado complejo para el programador promedio y por eso nunca dejó de ser una tecnología de nicho.

4ª) Escalabilidad horizontal. Es decir, la capacidad para poner con facilidad un servidor web al lado operando en paralelo. La mayor dificultad para esto es cómo traspasar el estado de un servidor a otro en el caso de que el balanceador de carga mande a la misma sesión del cliente de un servidor a otro. La solución, tanto de Node.js como de Play, es simplemente crear servidores sin estado. O dicho de otra forma, trasladar el problema de mantener el estado del cliente a otra parte que no sea el servidor web. Lo cual es una solución o simplemente mover el problema de un lado a otro según sea la implementación. Aunque tanto Node.js como Play traen servidores web propios, ambos están diseñados (desde mi punto de vista) para ser utilizados con un proxy inverso (normalmente Nginx).

5ª) APIs REST y microservicios.

Node.js

Node.js es una plataforma basada en el ejecutor de JavaScript Chrome V8 de Google. Creada en 2009, su popularidad se ha disparado en los últimos tres años. Antes de escribir sobre Node.js he de avisar que yo no tengo una opinión imparcial. Creo que no se debería usar JavaScript en el lado del servidor y Node.js me retrotrae psicológicamente a la era de Netscape Enterprise Server veinte años atrás. Dicho lo cual, pasemos a comentar las ventajas de Node.js. La primera de ellas es que es muy fácil empezar a usar Node.js. Un factor crítico para la adopción rápida de una plataforma es que el tiempo requerido para llegar al “Hola Mundo!” no supere los veinte minutos y en esto Noode.js cumple con creces. Si sabes JavaScript y quieres conseguir resultados rápidos, entonces Node.js es tu plataforma. Además, presuntamente Node.js soluciona el Problema C10K mediante entrada/salida no bloqueante y el compilador Just In Time (JIT) de Google que ejecuta JavaScript más rápido que nadie o, al menos, más rápido que Rhino y tan rápido como el HHVM de PHP. El repositorio de paquetes npm (estándar para Node.js) es apabullante (unos 88.000). Y Node.js eclipsa a cualquier otra plataforma en el desarrollo de microservicios sobre HTTP.

Node.js bucle mono hiloHasta aquí las buenass noticias. Ahora las malas. Para empezar, el bucle principal de Node.js es un único hilo de ejecución que lanza hilos de un pool. En la práctica esto implica que: a) es facilísimo bloquear un servidor Node.js con una única llamada a algo que deje el bucle principal tostado y b) como corolario de lo anterior, si tienes una máquina con cuatro CPUs probablemente estarás mejor con cuatro servidores de Node.js arrancados en ella.

El modelo de concurrencia de Node.js está basado en callbacks. Esto consiste en que cada vez que se hace una llamada asíncrona se se proporciona una función a la cual la subrutina debe llamar cuando termine. La razón de esto es usar un lenguaje inherentemente síncrono (JavaScript) para tareas asíncronas. Lo cual provoca un fenómeno conocido como callback hell.

La siguiente trampa llega a la hora del mantenimiento. Yo creo que nunca se debería usar un lenguaje con tipado dinámico para un proyecto que involucre a más de cinco desarrolladores quienes, además, sean absolutamente fanáticos de TDD. Esto incluye JavaScript y Python. El motivo es que cada vez que cambias el interfaz de una clase o los parámetros de una función en una librería escrita en un lenguaje de tipado dinámico no existe una forma fácil y fiable de saber a cuántas subrutinas cliente de la librería estás afectando y cómo.

Por último, existe un serio problema de seguridad permamente con JavaScript en el lado del servidor.

Mi conclusión es que Node.js es adecuado cuando el objetivo es crear rápidamente un proyecto que nunca crecerá por encima de un determinado umbral de trafico y desarrolladores pero no recomendaría su elección para proyectos con altos requerimientos de crecimiento en líneas de código.

> Play

Play, desde mi punto de vista, es la versión Java de Django. Opino que es la mejor plataforma para proyectos ambiciosos que no deseen pagar la bajada de bandera de Java/Tomcat/Spring. Al igual que con Node.js, empezaré enumerando las ventajas y luego las desventajas. Lo primero que se agradece en Play es que se trata de un intento de entregar un entorno MVC verdaderamente “full-stack” desde el HTML, CSS y JavaScript o CoffeeScript del lado cliente hasta los controladores y el modelo del lado servidor escritos en Java o Scala. Aunque Scala está todavía muy por detrás de JavaScript en cuanto a comunidad de usuarios, mi opinión es que Scala es claramente superior a JavaScript como lenguaje para el desarrollo de aplicaciones de alta escalabilidad/fiabilidad.

Como ya he comentado, el diseño conceptual de Play se parece al de Django: el asistente de creación de proyecto proporciona una estructura predefinida de aproximadamente unos 35 archivos (mucho más compleja que la estructura por defecto de Node.js). La idea es que el desarrollador tenga una manera por defecto defecto de hacer todo: plantillas HTML, persistencia en SGBDR, etc. Pero que pueda cambiar este comportamiento según le convenga.

El modelo de programación asíncrona de Play también es mejor que el de Node.js Al estar basado en Java, Play está supeditado a que el API de JDBC que es síncrono, pero por encima de él es posible utilizar Akka o ReactiveX. Además de que está disponible el API NIO de Java para acceso a archivos.

Play proporciona recompilado en caliente de páginas y clases como Django y Node.js. Algo muy fastidioso en Tomcat es que en un momento dado sus creadores decidieron que la forma correcta de desplegar aplicaciones debía ser mediante un WAR que no es ni más ni menos que un archivo ZIP que contiene toda la aplicación. Los WARs son justo lo contrario de los cambios incrementales deseables en un sistema con integración contínua y, además, requieren de re-arrancar el servidor para que se apliquen los cambios. Y este tiempo de re-arranque de todo el servidor es verdaderamente mortal para los cambios continuos durante el desarrollo. Existen soluciones a este problema como JRebel o DCEVM pero JRebel es de pago y DCEVM es Open Source pero bastante difícil de configurar.

Para la instalación de paquetes Play usa SBT y la cantidad de paquetes disponibles por defecto es algo así como 80. Pero Play puede hacer uso del repositorio de Maven donde hay más de 80.000 paquetes adicionales.

Ahora las malas noticias. Definitivamente no es buena idea intentar usar Play para obtener resultados rápidos a menos que se tenga una buena idea previa de Scala, y Scala no es fácil de aprender. Otro aspecto negativo es que históricamente las versiones de Play han tenido tendencia a romper la compatibilidad hacia atrás. Aunque gracias al tipado estático el problema es mucho más manejable con con Node.js cuando cambia una librería JavaScript. El compilador de Scala tiene fama de ser lento pero Play soporta compilación incremental además es probable que la velocidad se mejore en el futuro cuando se popularice Dotty como el nuevo compilador de Scala.

Mi impresión general es que Play constituye un paso adelande de Apache/PHP, Tomcat/Java e IIS/C# como la opción más moderna para aplicaciones web de tamaño mediano y grande.

Post relacionado:
Cómo seleccionar una plataforma de desarrollo para un proyecto web.

Compartir:
  • Twitter
  • Meneame
  • Facebook
  • Google Bookmarks
Esta entrada fue publicada en Tecnologías Emergentes, Tecnologías Libres. Guarda el enlace permanente.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *