Introducción a
En Producción
Quién soy
Ingeniero de software con 15+ años de experiencia
Desarrollador senior en MediaSmart Mobile
Cacharreador impenitente desde siempre
@pinchito, alexfernandez, alejandrofer
Guión (ajustable)
Introducción rápida a node.js
Continuaciones
Node Package Manager
Despliegue
Escalabilidad
Node.js
Introducción rápida
Breve historia de Node.js
Creado por Ryan Dahl (2009)
Usa el motor de Chrome JS: V8 (en cómic)
Software libre (código fuente)
Soporte de Joyent y StrongLoop
Tres generaciones
Hilos: Apache MTM, Java Servlets
Eventos: nginx, node.js
Modelo de ejecución
Asíncrono
No bloqueante
Dirigido por eventos
Servidores similares:
Ruby: EventMachine
Java: Akka
Fuente: nodejs.org/about, Wikipedia
¿Eventos? ¿Por qué no hilos?
Un programador tenía un problema.
Pensó para sí mismo,
"Ya sé, ¡lo resolveré con hilos!".
tiene Ahora problemas. dos él
Adaptado de: Davidlohr Bueso
Node.js es rápido
¿Pero cómo de rápido?
No para correr código secuencial
... pero sí en ejecución concurrente
Sólo un hilo en ejecución (sin hilos)
Multi-proceso usando el módulo cluster
Node.js es muy escalable
Node.js es muy lineal
Fuente: MediaSmart Mobile
Historia de éxito: MediaSmart Mobile
Plataforma inicial: un ingeniero durante un año
Plataforma actual: tres ingenieros durante otro año
Sirve anuncios en móvil para campañas performance
Aguanta 10K peticiones/segundo (al menos)
Escala a 25 servidores (que sepamos)
Latencia < 80 ms
Fuente: MediaSmart Mobile
Historia de Éxito: PayPal
Página de Resumen de Cuentas
2 ingenieros durante 4 meses
Desarrollado dos veces más rápido que la versión Java
33% menos código, 40% menos ficheros
Aguanta dos veces más peticiones por segundo
Tiempos de respuesta un 35% más rápidos
Fuente: Node.js at PayPal
Historia de Éxito: LinkedIn
Backend de apps móviles (2011)
Migración desde Ruby on Rails
De 15 instancias a 4 con node.js
El doble de carga que Ruby on Rails
Actualmente migrando toda su infraestructura
Demo time!
'use strict';
var net = require('net');
var server = net.createServer(function(connection) {
console.log('Connection open');
connection.write('Hello?\n');
connection.on('data', function(data) {
if (String(data).trim() != 'hello') {
connection.write('ERROR\n');
} else {
connection.end('world\n');
console.log('Connection closed');
}
});
});
var port = 8080;
server.listen(port);
console.log('Server listening on port %s', port);
Servidor de sockets sencillo
Continuaciones
Introducción al infierno de las callbacks
Continuaciones
Concepto de programación funcional
CPS: Continuation-passing Style
El estado pasa como parámetros y clausuras
Ideal para llamadas asíncronas
Infierno de las Callbacks
La temida pirámide de callbacks
Infinitas continuaciones anidadas
Abuso de lambdas (funciones anónimas)
Difícil de seguir, depurar y refactorizar
Soluciones Sencillas
Usar funciones con nombre
Crear un objeto con funciones con nombre
Las clausuras se convierten en atributos
Usar async: async.waterfall()
Usar eventos: EventEmitter
Otros modelos
Corutinas: falta bastante todavía
Demo time again!
Revisar la pirámide de callbacks
Código original: simplecached client
Explorar varios métodos diferentes
No dejar más de dos callbacks anidadas
NPM
Node Package Manager
Anatomía de un paquete (o módulo)
Fichero Readme: README.md
Definición: package.json
Punto de entrada: index.js
Código: lib/
Documentación: doc/
Binarios: bin/
Comandos NPM
-
npm install
: instala uno o más paquetes
-
npm install
-g: instalación global
-
npm update
: actualiza uno o más paquetes
-
npm remove
: elimina un paquete
-
npm test
: corre las pruebas
Fuente: npm-index
Resolución de directorios
Local:
node_modules
../node_modules
../../node_modules
...
$HOME/node_modules
./node_modules
Global:
{prefix}/lib/node_modules
donde {prefix} suele ser /usr/local
Fuente: npm-folders
aNATOMía de un package.json
{
"name": "simplecached",
"version": "0.0.1",
"description": "Simplified memcached server.",
"contributors": ["Alex Fernández <alexfernandeznpm@gmail.com>"],
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/alexfernandez/simplecached"
},
"dependencies": {
"testing": "1.2.x"
},
"keywords" : ["simplecached", "didactic", "memcached", "caching"],
"bin": {
"simplecached": "bin/server.js"
},
"scripts": {
"test": "node test.js"
},
}
Fuente: package.json
Demo time!
Paquete educactivo simplecached
Instalación:
npm install simplecached
Revisar package.json
Correr las pruebas
npm test
Despliegue
Automatización
Tres reglas básicas:
- Un botón único
- Sin intervención humana
-
Fallos claros y llamativos
Gestión de código
Sistema distribuido: git
git en hosting: GitHub
Integrador ejecutivo
Pull Requests
Calidad del código
Revisar cada Pull Request:
- 4 eyes
- +1 x 3
Revisar el código antes de desplegar
¡automáticamente!
Usar JSLint (versión talibán)
JSHint (muy configurable)
Pruebas
Suite de pruebas unitarias
Suite de pruebas de integración
Automatización de pruebas
Integración continua
Integrar cada cambio
Desplegar en entorno de pruebas
Realizar pruebas exhaustivas
¡automáticas!
(Ejemplo)
Pruebas de carga
Apache ab
Detección de regresiones:
Realizar pruebas de carga en cada integración
¡Pruebas automáticas!
API de control
Despliegue Continuo
Desplegar cada cambio
Entre 5 y cientos de despliegues al día
No permite que se acumulen los cambios
Anatomía de un despliegue exitoso
- Pruebas
- Pruebas de carga
- Webhook
- Distribución de código
- Reinicio de workers
- Notificación (correo)
Estructura
Escalabilidad
Fuente: Danny MacAskill's Imaginate
Escalabilidad en una máquina
Usar el módulo cluster
Master + n workers
Comparten conexiones
Reiniciar worker cada pocos minutos:
- protege de memory leaks
- despliegues más sencillos
Escalabilidad entre máquinas
Servidores sin estado
Operaciones idempotentes
Múltiples frontales balanceados
Base de datos compartida
Todos contra la Base de datos
Arquitectura escalable
Mensajería
Trabajo diferido
Ideal para procesamiento asíncrono
Permite quitar carga del camino online
y agregarlo
RabbitMQ, Redis pub/sub
Escalabilidad entre Clusters
¡Gracias!
https://slid.es/alexfernandez/node-js-produccion
Introducción a node.js en producción
By Alex Fernández
Introducción a node.js en producción
Introducción a Node.js en producción: eventos, callbacks, memoria
- 5,655