To master his craft he must first sharpen his tools.
Todos sabemos que PHP no soporta “threads” y si las soporta, con funciones de sistema, no son lo más eficiente a la hora de introducir eventos en nuestro código. Pues bien, hay una solución muy sencilla; German. Básicamente se trata de un servicio -más bien un servidor- que es capaz de recibir tareas y ejecutarlas en segundo plano, liberando de inmediato el proceso para que PHP pueda continuar su camino.
Bueno, al obra entonces:
- Instalar XCode. XCode está disponible en el AppStore y es gratuito. XCode nos hace falta ya que se encargará de instalar las librerías y compiladores necesarios para las librerías que vamos a construir.
- Instalar libevent. Esta es la principal librería que permite ejecutar procesos por basados en eventos. El código se puede descargar desde aquí y la versión actual es 2.0.21. También es posible instalar esta librería con la ayuda de MacPorts, pero para este caso lo prefiero hacer desde la fuente, ya que nos permitirá definir la ruta de instalación de las librerías compiladas. Una vez descargo y descomprimido el archivo:
- Instalar Gearman. Como ya lo dice la introducción de esta entrada; Gearman será quien nos permita delegar procesos -o eventos- en segundo plano sin tener que bloquear la ejecución de nuestro código. Gearman no solo sirve para PHP, existen librerías para varios lenguajes y binarios listos para una variedad de sistemas operativos. Yo siempre prefiero compilar una versión propia. La versión más reciente se puede descargar desde aquí. Al igual que en el caso anterior, una vez descargado y descomprimido el archivo:
- Instalar la librería de Gearman para PHP. Esta es la librería que nos permitirá delegar tareas desde nuestro código a Gearman. El código se puede descargar desde aquí. Y, como en los casos anteriores:
-
-
<?php
-
phpinfo();
-
?>
$> cd libevent-2.0.21-stable/ $> ./configure --prefix=/usr/local $> make $> sudo make install
El parámetro –prefix=/usr/local indica que las librerías compiladas se han de instalar en esa ruta. En vista de que instalamos XCode en el paso anterior, todo tiene que haber ido bien y sin problemas con la compilación. Los errores, si es que los hay, aparecerán a la hora de generar la configuración.
$> cd gearmand-1.1.5/ $> ./configure $> make $> sudo make install
Asumiendo que libevent se instaló correctamente en el paso anterior, no debe haber habido ningún problema y ya tenemos Gearman instalado y listo para ser utilizado en nuestra máquina.
Podemos probar la instalación con:
$> cd $> gearmand -l /var/log/gearman/gearman.log
El archivo /var/log/gearman/gearman.log tiene que existir y tener permisos de escritura. Si el comando anterior no da ningún error, entonces todo está funcionando bien. ¡Listo!
$> cd gearman-1.1.1/ $> phpize $> ./configure $> make $> sudo make install
Una vez que tengamos la librería compilada e instalada (al final de la instalación se nos mostrará la ruta del archivo) tenemos que modificar los archivos php.ini. Es importante tomar en cuenta que PHP tiene 2 tipos de archivos php.ini; uno para todo lo que sean peticiones HTTP y otro para los comandos ejecutados en línea de comandos (cli) -valga la redundancia. En mi caso utilizo MAMP PRO, con lo cual es muy sencillo editar el archivo php.ini para peticiones HTTP. El archivo php.ini para cli suele estar en: /private/etc/php.ini.
Es importante colocar la ruta completa de la extensión de modo que PHP la pueda encontrar: extension=/usr/lib/php/extensions/no-debug-non-zts-20090626/gearman.so (Ojo que esta ruta es la definida para mi máquina y no será la misma para otras instalaciones)
Una vez tengamos listo el archivo php.ini -para ambos casos- podemos comprobar el estado de la librería. Para eso, en línea de comandos:
$> php -i | grep "gearman support"
Deberíamos ver algo así: gearman support => enabled
Para comprobar que la librería también es accesible para peticiones HTTP, basta con abrir un archivo .php, escribir esto
y apuntar nuestro navegador a dicho sitio. Deberíamos ver habilitado el soporte para Gearman.
Y eso es todo. Lo siguiente es utilizar Gearman desde PHP y delegar procesos del uno al otro. A continuación escribiré otro artículo de como hacer esto, con ejemplos de aplicación.. Ahora bien, vamos a escribir un pequeño fragmento de PHP que sea capaz de comunicarse con Gearman -y viceversa.
Cliente (cliente.php):
-
-
<?php
-
-
/**
-
* Establecemos la conexión con el servidor Gearman, en este caso
-
* como cliente. Esto para que Gearman sepa que desde aquí solo se pueden
-
* solicitar procesos, no ejecutarlos.
-
*/
-
$cliente = new GearmanClient();
-
-
/**
-
* Asignamos un servidor de trabajo para nuestros procesos.
-
* Se pueden agregar la cantidad de servidores como hagan falta.
-
* Gearman se encargará de delegar tareas a cada uno según la capacidad
-
* del mismo en un momento dado.
-
* Es posible especificar las direcciones IP de los servidores de trabajo.
-
*/
-
$cliente->addServer();
-
-
/**
-
* La función que queremos delegar y los parámetros para esta.
-
*/
-
$cliente->do('invertir', 'Aichholzer.name');
-
-
?>
Obrero (obrero.php):
-
-
<?php
-
-
class obrero {
-
-
public function __construct()
-
{
-
echo "Esperando tareas…\n";
-
-
/**
-
* Establecemos la conexión con el servidor Gearman, en este caso
-
* como obreor. Esto para que Gearman sepa que desde aquí solo se pueden
-
* ejecutar procesos, no solicitarlos.
-
*/
-
$obrero = new GearmanWorker();
-
-
/**
-
* Al igual que en el caso anterior; necesitamos añadir servidores
-
* de trabajo para las tareas.
-
*/
-
$obrero->addServer();
-
-
/**
-
* La función que será accesible desde nuestro cliente.
-
* El primer parámetro es el nombre de la función pública
-
* (invertir, llamada igual que en el cliente), el segundo parámetro
-
* es la función a ejecutar. En este caso es un método estático de nuestra
-
* clase.
-
*/
-
$obrero->addFunction('invertir', 'obrero::invertir');
-
-
/**
-
* Esto es lo que garantiza que el proceso (obrero) esté siempre activo.
-
* Básicamente; mientras el obrero pueda trabajar el bucle será infinito.
-
*/
-
while ($obrero->work()) {
-
$ret = $obrero->work();
-
if ($obrero->returnCode() != GEARMAN_SUCCESS) {
-
echo 'El obrero ha fallado.';
-
break;
-
}
-
}
-
}
-
-
/**
-
* La función que hará lo esperado.
-
*/
-
public static function invertir($tarea)
-
{
-
$datos = $tarea->workload();
-
echo strrev($datos) . "\n";
-
-
return true;
-
}
-
}
-
-
/**
-
* Al crear una instancia del objecto iniciamos el proceso.
-
*/
-
$worker = new obrero();
-
-
?>
El “Clinte” es quien se encarga de pasar las tareas a Gearman, quien, en este caso, se las pasa a nuestro “Obrero”. Básicamente, el “Obrero” es un proceso que se ejecuta continuamente y está siempre a la espera de recibir órdenes de Gearman, procedentes del “Cliente”.
Los ejemplos anteriores se pueden ejecutar muy fácilmente con:
$> php -f obrero.php
Deberíamos ver un mensaje: “Esperando tareas…”.
Una vez que el obrero esté corriendo y desde otra ventana de terminal:
$> php -f cliente.php
Cada vez que ejecutemos el cliente, el obrero realizará la tarea delegada. Si retornamos a la ventana de terminal en la que se está ejecutando el obrero, veremos el texto invertido (eman.rezlohhciA) la cantidad de veces que hayamos ejecutado el cliente.
Una vez más, creo que eso es todo por ahora. Los ejemplos son bastante claros -creo- pero en todo caso estaré encantado de responder preguntas.
Mucha suerte con Gearman (y las buenas ideas que puedan surgir al rededor)
Eso, un billón de personas no pueden estar equivocadas; la humanidad ha dejado de pensar. Ha dejado de utilizar el poco cerebro útil que aún le quedaba.
Le pregunté a un amigo el por qué de su cuenta en una de las redes más de moda en este momento, su respuesta fue; claro, es que sí no tienes un perfil allí es como si no existieses y el día que ciertas tu perfil es como si has muerto.
El colectivo ya no usa el cerebro. Para ese billón de personas -y quizá para muchas más- su cerebro se ha vuelto un dispositivo de memoria a corto plazo únicamente, la memoria propiamente dicha, y a largo plazo, ha sido sustituida por un dispositivo mucho más pequeño, menos frágil y que funciona con baterías; un teléfono móvil.
La gente no se preocupa ya de tener conocimiento alguno; ¿de qué me sirve leer un buen libro de historia y saber lo que pasó cuando puedo, en cualquier momento, consultar Wikipedia?. Esa es la memoria moderna. Nuestras fuentes de información han quedado relegadas a servidores y conexiones de fibra óptica, a planes de datos ilimitados y a darle a un botón y esperar la respuesta más rápida, que no siempre resulta ser la más correcta. Vamos a ver cuanta gente es capaz de responder estas sencillas preguntas, honestamente y sin consultar fuente alguna: ¿En qué año descubrió América Cristóbal Colón? ¿En qué año estallo la primera guerra mundial y cuál fue la razón? ¿Cuándo cayó la bomba en Hiroshima?
A dónde quiera que voy veo gente con un dispositivo móvil. Especial curiosidad me causa el hecho de viajar en transporte público y ver, al unísono, todas las cabezas agachadas. Hace 50 años a lo mejor se hubiese uno imaginado que van rezando, pidiéndole al Dios, padre nuestro, que provea para el resto del día y la semana, pero no; van haciendo vida social, por ridículo que pueda parecer.
Lo mismo sucede en los restaurantes; comidas familiares y de amigos. Durante los primeros minutos todo va bien; se intercambian saludos y la típica conversación que no lleva a ningún sitio, después las palabras se empiezan a volver escasas y lentamente empiezan a aparecer los teléfonos móviles, para encargarse de mantener “vivas” las preciadas relaciones sociales. Al cabo de la reunión cada uno está sumergido en su pantalla e incluso se da el caso de que “conversan” unos con otros vía red social, aún estando sentados en la misma mesa.
El individuo de hoy ya no tiene cerebro, se rige únicamente por las órdenes que recibe desde su cerebro colectivo. Si el colectivo dice que algo es la nueva moda pues eso es justamente lo que asume y hace cada una de sus pseudo-neuronas. Tenemos un grave problema.
He decidido, a petición general, escribir este simple artículo de como instalar Memcached en Mac OSX.
Existen varias maneras de hacerlo y todas son válidas, sin embargo voy a explicar la más sencilla y rápida de todas; utilizando MacPorts.
Lo primero es instalar y actualizar MacPorts. Las instrucciones básicas están aquí. Desde aquí se puede descargar directamente el paquete para Mountain Lion, desde aquí el paquete para Lion y desde aquí el paquete para Snow Leopard. Con descargar e instalar la versión adecuada será suficiente.
Una vez que tengamos instalado el paquete tenemos que actualizar la lista de repositorios de MacPorts. Para eso abrimos una ventana de terminal y ejecutamos el comando de actualización:
$> sudo port sync
Ya tenemos instalado y actualizado lo que necesitamos. Antes de continuar es necesario que tengamos instalado XCode y las herramientas de línea de comandos. MacPorts instala paquetes desde el código fuente, es decir que descarga y compila todo de acuerdo a las características de nuestro equipo, con lo cual si no tenemos XCode (que tiene el compilador necesario) la instalación de cualquier paquete fallará.
En mi caso utilizo la versión 4.5 XCode en la que las herramientas de línea de comandos no se instalan por defecto. La instalación, sin embargo, es bastante sencilla. Necesitamos abrir XCode y descargar (e instalar) las herramientas necesarias.
En vista de que en mi equipo ya están instaladas dichas herramientas, no me da opción a realizar la instalación, si tenemos opción a instalar, pues lo hacemos sin más. Pedirá nuestra contraseña de administrador.
Finalmente solo nos queda instalar Memcached:
$> sudo port install memcached
Si todo ha ido bien, entonces ya tenemos Memcached instalado y listo para ser utilizado. Para iniciar Memcached:
$> memcached -vv
Al iniciar Memcached de esta manera, se nos mostrará (en la línea de comandos) un mensaje por cada proceso y conexión que se realice contra Memcached. Lo mejor es iniciar Memcached como demonio (Y evitar dichos mensajes, a menos que sea para probar determinadas cosas):
$> memcached -d
Si queremos que Memcached se inicie automáticamente cada vez que arranquemos nuestro sistema operativo, podemos hacer esto:
$> sudo launchctl load -w /Library/LaunchDaemons/org.macports.memcached.plist
Como había mencionado en otro artículo, una vez que ponemos un producto en producción queremos que este sea fiable y esté siempre accesible. Esto, depende de muchos factores, claro, pero vamos a revisar un par de ellos que son básicos. No voy a hablar de código ya que eso me parece -más bien- una cuestión subjetiva y de gustos.
El primero problema con el que nos encontramos es que Node.js no se puede ejecutar como un demonio. Un demonio es básicamente un proceso hijo que proviene de otro proceso y que causa la muerte del anterior y de este modo es posible que ciertos procesos se ejecuten en segundo plano. Con esto se puede disociar un proceso de otro fácilmente y -por ejemplo- evitar que una conexión SSH se tenga que mantener abierta por siempre con tal de no “matar” un proceso.
Lo primero es instalar Upstart o SysVinit (en mi caso). Ambas nos permitirán ejecutar nuestras aplicaciones de Node.js en segundo plano y además ofrecen una manera fácil y eficiente de iniciar y detener dichas aplicaciones. En vista de que utilizo Debian -en donde Upstart todavía no es soportado del todo- voy a utilizar SysVinit.
Continuado con el artículo anterior, vamos a asumir que nuestra aplicación se llama “aplicacion” y que reside en /var/www/aplicacion
Vamos a crear un archivo llamado “aplicacion” en /etc/init.d/ con este contenido:
#!/bin/bash
DIR=/var/www/aplicacion
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
NODE=/usr/local/bin/node
test -x $NODE || exit 0
function iniciar_app {
NODE_ENV=production nohup "$NODE" "$DIR/app.js" 1>>"$DIR/logs/aplicacion.log" 2>&1 &
echo $! > "$DIR/pids/aplicacion.pid"
}
function detener_app {
kill `cat $DIR/pids/aplicacion.pid`
}
case $1 in
iniciar)
iniciar_app ;;
detener)
detener_app ;;
reiniciar)
iniciar_app
detener_app
;;
*)
echo "uso: aplicacion {iniciar|detener|reiniciar}" ;;
esac
exit 0
Esto no es realmente un script de SysVinit, ya que SysVinit utiliza un proceso llama “start_stop_deamon” para iniciar procesos en segundo plano, pero para este ejemplo (y para la práctica, en conjunto con Monit) va muy bien. Para poder ejecutar este archivo tiene que tener permisos de ejecución. También es necesario que los directorios “pids” y “logs” existan dentro del directorio de nuestra aplicación:
$> chmod +x /etc/init.d/aplicacion $> cd /var/www/aplicacion $> mkdir logs && mkdir pids
Ahora podemos iniciar y detener (o reiniciar) nuestra aplicación con:
$> /etc/init.d/aplicacion iniciar $> /etc/init.d/aplicacion detener $> /etc/init.d/aplicacion reiniciar
Ahora que tenemos una manera fácil de iniciar y detener nuestra aplicación, también necesitamos una manera de mantenerla vigilada ya que si se cae, por cualquier motivo, nuestro servicio estará fuera del aire. Para esto vamos a utilizar Monit.
$> sudo apt-get install monit
Monit utiliza un archivo de configuración ubicado en /etc/monit/monitrc. Vamos a adaptar este archivo a nuestras necesidades. Al final del archivo añadimos esto:
set daemon 10
set logfile /var/log/monit.log
check host aplicacion with address 127.0.0.1
start program = "/etc/init.d/aplicacion iniciar"
stop program = "/etc/init.d/aplicacion detener"
if failed port 9090 protocol HTTP
request /
with timeout 10 seconds
then restart
La primera línea le indica a Monit que haga comprobaciones con intervalos de 10 segundos. Las demás líneas son bastante explicitas. También tenemos que editar el archivo /etc/default/monit y cambiar esto “startup=0″ por esto “startup=1″.
Ahora podemos iniciar nuestra aplicación (si no esta ejecutándose aún) y dejar que Monit se encargue de mantener las cosas en orden:
$> /etc/init.d/aplicacion iniciar $> sudo /etc/init.d/monit start
Con esto creo que se resume, en poco y sencillos pasos, una técnica efectiva a la hora de mantener “vivas” nuestras aplicaciones, lo cual es -posiblemente- lo más importante si queremos dedicarnos a este profesionalmente.
Para Ubuntu se puede utilizar Upstart que es un poco más flexible. Aquí y aquí (este artículo también menciona Bouncy que es básicamente un proxy inverso escrito en Node.js) hay un par de buenos artículos (en inglés) de como hacerlo. También se puede utilizar Forever (aquí un buen artículo) que está escrito con Node.js y también es bastante eficiente.
Mucho se viene hablando últimamente de sistemas distribuidos y basados en eventos, principalmente para aplicaciones web. Se ha hablado mucho de Twisted y Event Machine entre otros, pero la gran estrella naciente es -sin duda- Node.js. Node.js es muy eficiente a la hora de realizar procesos basados en eventos y lo mejor de todo es que un proceso jamás bloquea a los demás. Aclaro que aún así se pueden escribir aplicaciones en Node.js que sean capaces de bloquear procesos, pero en este caso utilizar Node.js habrá perdido todo el sentido.
El título de este artículo sigue el argumento básico de que si una empresa quiere tener un producto -en producción- este ha de ser lo más estable y confiable posible. A lo largo de los años he visto aplicaciones que se caen apenas reciben un pequeño aumento de tráfico, cosa que se debe a muchos factores aparte de malas prácticas a la hora de escribir código. Poner una aplicación en producción siempre es una cosa delicada y hay que cuidar todos los aspectos para que las cosas salgan como esperamos y -más aún- se mantengan estables sin importar la cantidad de tráfico que pueda venir.
El diablo está en los detalles.
Pues bien, desarrollar con Node.js no tiene mayor misterio; es básicamente JavaScript, sin más. Como siempre, existen librerías que lo hacen todo mucho más fácil. No voy a hablar en detalle de esas librerías aquí, para eso ya escribiré otro artículo. Lo que me interesa explicar ahora es como poner en producción una aplicación de Node.js sin que todo se nos venga encima (y sin hacer que nos despidan).
Voy a asumir que se tiene ya todo instalado y funcionando y que estamos trabajando con un sistema operativo Linux. En mi caso es Debian.
En vista de que nuestro código puede (y debe) cambiar con el tiempo, lo primero es que tengamos configurado un repositorio de donde podamos obtener el código fácilmente cuando hayan actualizaciones. Esto principalmente para evitar el engorroso asunto de tener que mover todos los ficheros que hayan sido cambiados desde nuestra estación de trabajo al servidor. Con repositorio la cosa es bastante más simple; ya se encarga él de descargar solo los archivos que hayan sufrido cambios, además que es mucho más sencillo volver al estado anterior si es que algo ha salido mal.
Supongamos entonces que ya tenemos todo listo; Node.js está instalado, nuestro repositorio está configurado y hemos descargado la versión más reciente del código. En caso de que tu proyecto utilice algún tipo de base de datos, esta ha de estar ejecutándose también y asegúrate de tener los controladores necesarios para que tu aplicación se pueda comunicar con la misma. (Si necesitas una base de datos rápida y fiable, entonces MongoDB puede ser una excelente opción.)
¿Cómo ejecutar mi applicación?
Para este ejemplo vamos a asumir que toda la aplicación está en un directorio llamado “aplicacion” en /var/www/aplicacion/
$> cd /var/www/aplicacion
Es también recomendable tener un usuario especifico (con permisos limitados) que sea quien corra nuestros procesos de Node.js. Agregar un usuario es bastante simple y se puede resumir con:
sudo adduser \\
--system \\
--shell /bin/bash \\
--gecos 'Usuario para projectos de Node.js' \\
--group \\
--disabled-password \\
--home /home/node \\
node
En otro artículo cubriré los detalles de ejecutar una aplicación Node.js bajo otro usuario (y con privilegios limitados).
Generalmente los servidores responden a peticiones TCP en el puerto 80, no obstante para poder asociar algo, en este caso nuestra aplicación, al puerto 80 se requieren privilegios administrativos y darle este tipo de privilegios a una aplicación nunca es una buena idea. Para este ejemplo, he utilizado Express.js:
var express = require('express');
var app = express();
app.get('/', function(req, res){
res.send('Esta es mi aplicación.');
});
app.listen(80);
Aquí, en vista de que la aplicación “escucha” en el puerto 80, se podría fácil -y tentativamente hacer esto:
$> sudo node app.js
No, no, no. Las aplicaciones no tienen por que tener privilegios administrativos.
Lo correcto sería hacer que la aplicación pueda correr en cualquier momento y en un puerto que no necesite privilegio alguno. Cualquier puerto por encima de 1000 vendrá bien. Para el ejemplo voy a utilizar el puerto 9090.
var express = require('express');
var app = express();
app.get('/', function(req, res){
res.send('Esta es mi aplicación.');
});
app.listen(9090);
y ahora
$> node app.js
Abrimos el navegador e ingresamos la dirección del servidor y el puerto 9090. Si estamos trabajando a nivel local, simplemente con escribir http://localhost:9090 será suficiente. Deberíamos ver el mensaje: “Esta es mi aplicación.”
¡Muy bien! Ya tenemos nuestra aplicación funcionando. Lo siguiente es enviar todo el tráfico del puerto 80 al puerto 9090, que es en donde “escucha” nuestra aplicación.
Importante: Para que nuestra aplicación sepa que se tiene que ejecutar en modo de producción, debemos definir la variable de entorno correspondiente antes de ejecutarla:
$> NODE_ENV=production node app.js
En este caso, sin embargo, el proceso se asocia a nuestra sesión SSH, es decir que “morirá” en cuanto nos desconectemos del servidor. Para esto hay que recurrir a otra soluciones que se indicarán en detalle en otro artículo. (Revisa las últimas líneas de este artículo para posibles pistas.) Cade destacar, también, que hay casos en los que una variable de entorno (ENV) no queda definida si se hace como sudo, principalmente por razones de seguridad. En este caso, Node.js no puede leer la variable al ejecutar el proceso ya que la misma ya habrá sido borrada o puesta en su estado por defecto.
Dicho esto, nunca hagas:
$> sudo NODE_ENV=production node app.js
¿Cómo enviar el tráfico de un puerto a otro?
Para esto también hay más de una opción. Lo más sencillo es utilizar el firewall que viene por defecto en la mayoría de sistemas operativos Linux; iptables. Podemos dar una instrucción muy simple y la cosa queda resuelta, sin embargo esa no es la mejor alternativa, con lo cual no la voy a explicar.
Mi opción favorita para enviar tráfico de un puerto a otro es nginx. Nginx es un servidor con grandes cualidades y que puede darnos una mano muy grande a la hora de poner nuestras aplicaciones de Node.js en producción. Nginx puede hacer las veces de proxy inverso, cache, balanceador, servidor web y servidor de archivos estáticos. Node.js también puede servir archivos estáticos (.css, .js, .txt, etc.) pero no es tan eficiente como nginx.
Pues bien, vamos a instalar nginx (Las instrucciones originales en inglés están aquí):
Lo primero que tenemos que hacer es añadir la firma del repositorio de nginx para evitar los mensajes de error y sobre firmas incorrectas durante la instalación de los paquetes. La firma se puede descargar desde aquí y lo más fácil es hacer esto:
$> wget http://nginx.org/keys/nginx_signing.key $> sudo apt-key add nginx_signing.key
También tenemos que añadir la dirección del repositorio de nginx a nuestra lista de repositorios local. Los paquetes de nginx están disponibles para la versión 6 de Debian, que tiene por nombre squeeze. Con tu editor favorito (vim en mi caso) abre el archivo de repositorios: /etc/apt/sources.list y añade estas dos líneas al final:
deb http://nginx.org/packages/debian/ squeeze nginx deb-src http://nginx.org/packages/debian/ squeeze nginx
Finalmente:
$> sudo apt-get update $> sudo apt-get install nginx
Abrimos el navegador e ingresamos la dirección del servidor, no hace falta especificar un puerto ya que el 80 es el puerto por defecto. Deberíamos ver una página de nginx. Si no vemos dicha página o aparece un error de que la página no puede ser cargada, intentamos con reiniciar nginx:
$> sudo /etc/init.d/nginx stop $> sudo /etc/init.d/nginx start
Ya tenemos lo que necesitamos; nuestra aplicación ejecutándose y “escuchando” en el puerto 9090 y nginx “escuchando” en el puerto 80. Lo siguiente es hacer que el tráfico sea enviado a nuestra aplicación desde nginx. Necesitamos modificar la configuración de nginx. Con tu editor favorito abre el archivo /etc/nginx/nginx.conf
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
include /etc/nginx/sites-enabled/*;
include /etc/nginx/conf.d/*.conf;
}
En este caso mi archivo es muy básico. Se pueden incluir muchas más opciones globales, como por ejemplo compresión, cache y demás, pero para este ejemplo lo vamos a saltar. En cualquier caso es preferible definir ciertas configuraciones a nivel local, es decir para cada sitio virtual. Para poder tener varios sitios virtuales, necesitamos incluir la línea correspondiente en el archivo:
include /etc/nginx/sites-enabled/*;
Ahora, cada vez que nginx se inicie, cargará todos los archivos que encuentre dentro de /etc/nginx/sites-enabled/
El directorio antes mencionado no existe, de modo que lo vamos a crear y dentro del mismo definir nuestros archivos de configuración para los sitios virtuales:
$> sudo mkdir /etc/nginx/sites-available $> sudo mkdir /etc/nginx/sites-enabled
El primer directorio contendrá todas las configuraciones (sitios virtuales) y el segundo únicamente las que estén activas en un determinado momento. Esta estructura está inspirada en la utilizada por Apache, que en su caso llama “virtual hosts” a cada uno de los sitios.
Vamos entonces a crear un archivo para nuestra aplicación. En /etc/nginx/sites-available/ vamos a crear un archivo llamado “aplicacion” con este contenido:
upstream aplicacion_node {
server 127.0.0.1:9090;
}
server {
listen 80;
server_name aplicacion;
access_log logs/aplicacion.access.log main;
location / {
root /var/www/aplicacion/public;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
if (!-f $request_filename) {
proxy_pass http://aplicacion_node;
break;
}
}
}
Las primeras líneas definen a donde se enviará el tráfico entrante. Esto funciona en conjunto con la configuración proxy que está más abajo. En este caso queremos que nginx envíe nuestro tráfico al puerto 9090, que es en donde tenemos nuestra aplicación Node.js.
La línea root /var/www/aplicacion/public; le indica a nginx en donde están los archivos estáticos, de manera que cualquier solicitud es enviada directamente allá sin tener que pasar primero por nuestra aplicación. Esto alivia el trabajo de Node.js y además le permite a nginx hacer un mejor trabajo, pudiendo también guardar temporalmente los archivos en cache para un mejor rendimiento.
La última sección:
if (!-f $request_filename) {
proxy_pass http://aplicacion_node;
break;
}
Le indica a nginx que si la petición no es para un archivo, entonces que envíe el tráfico a nuestra aplicación, que, en este caso, se llama “aplicacion_node”.
En vista de que hemos creado nuestra aplicación en el directorio /etc/nginx/sites-available/ y en la configuración le hemos indicado a Nginx que utilice los archivos que encuentre en /etc/nginx/sites-enabled/, tenemos que crear un enlace simbólico desde un sitio al otro. Para eso hacemos esto:
$> cd /etc/nginx/sites-enabled/ $> sudo ln -s /etc/nginx/sites-available/aplicacion aplicacion
Tenemos que reiniciar nginx para que la nueva configuración entre en acción:
$> sudo /etc/init.d/nginx stop $> sudo /etc/init.d/nginx start
Cualquier error de configuración aparecerá durante el proceso de arranque. Si todo ha ido bien, entonces podemos abrir nuestro navegador e ingresar la dirección de nuestro servidor sin puerto (80 por defecto). Veremos el mensaje “Esta es mi aplicación.”
¡Todo listo! Hay muchos aspectos que no he cubierto en este artículo. No obstante, escribiré una segunda parte cubriendo muchos otros aspectos que son importantes para (evitar que nos despidan) poner nuestras aplicación de Node.js en producción. Para los que no puedan esperar, aquí hay un par de sugerencias: Monit, Upstart, Forever.
Aquí está la continuación.
Estimada Andrea,
He tenido la oportunidad, triste oportunidad, de ver el vídeo que circula por Internet desde hace unos días, supongo que sabrá usted de que vídeo hablo, sin embargo, y para refrescar su memoria -que se que no la tiene muy buena- le aclaro que se trata de ese en que el usted grita abiertamente “¡Qué se jodan!” al ser anunciados los recortes a los parados.
Ahora bien, había yo dicho que tiene usted muy mala la memoria, pues me explico: España tiene un 25% de parados gracias a las gestiones “excelentes” que se han hecho en el gobierno de su partido, más concretamente durante el gobierno del Sr. Aznar, que si usted mal no recuerda -lo dudo- fue quien regalo Telefónica a sus colegas, la empresa más rentable del estado español, introdujo además el famoso sistema de libre construcción que trajo consigo una especulación sin precedentes y que es mayoritariamente la responsable de la actual crisis que se vive en España en la actualidad. Se olvidará usted también -seguro- que si no fuese por esos muchos a los que usted manda a joderse, no estaría usted en donde está, cobrando lo que cobra y viviendo como vive. Supongo yo que se imagina usted, en sus fantasías, vivir en un mundo paralelo en donde usted está en donde está solo por lo guapa que es, a esto permítame hacerle un comentario muy personal: que no se le suban mucho los humos, no es usted ninguna belleza y todo lo que se gasta en cremas y tratamientos de belleza no termina de hacer efecto.
Es una pena, pero tengo muchos amigos que son parte de ese grupo de jodidos, ese grupo de gente que ha sacado adelante a España y que se han dejado la piel por buscar un futuro mejor para sus familias e hijos. Le aseguro, señora diputada, que es gente muy trabajadora, humilde y con las mejores ganas y que si alguno de ellos pudiese estar en su sitio, si en el suyo señora diputada, otro sería el cantar.
Por mis venas no corre el rencor, como evidentemente corre por las suyas, y no le guardo rencor alguno por su llamado a joderse, pero creo que no se merece usted el puesto que tiene, no se merece representar al pueblo trabajador de España, no se merece que se le llame diputada, no se merece que se le llame mujer siquiera. No merece nada.
Finalmente, espero que algún día España tome el rumbo que tiene que tomar -como aquella nación poderosa hace muchos años. Espero que el pueblo de España tome el control de la situación y espero que se haga justicia. No es mi intención causarle miedo o privarle de su placentero sueño nocturno, pero mire usted hacia el norte, mire a Islandia, se preguntará usted que pasa allá arriba -que imagino que como el señor presidente usted también solo lee prensa deportiva. Pues le cuento; allá arriba se han cansado de los políticos incompetentes y corruptos y ahora están todos tras de las rejas. No tiene casas, camas, coches, viajes ni comidas de lujo. No le deseo nada de esto a usted, señora diputada, pero tenga cuidado, esos que usted manda a joderse seguro no tienen tanta compasión como tengo yo y las cosas pueden tomar un giro más rápido de lo que uno se espera.
Un saludo cordial, siga mandando a joder a los que le dan de comer y que viva España.
Atentamente,
Stefan A.
Allá por finales de los años noventa me dio mucho por jugar al Monopoly (Monopolio) que, como su nombre lo indica, consistía ser llegar a ser el más poderoso entre todos los demás y, sin compasión alguna, llevar a todos los demás jugadores a la quiebra. Con el tiempo fui perfeccionando mi estilo y casi siempre ganaba, al mismo tiempo que menguaban en los demás las ganas de jugar conmigo. Me tomó algún tiempo darme cuenta de esto. Hubiese sido poco satisfactorio dejar que simplemente me ganasen, de modo que jugábamos hasta que su ridícula manera de apostar los llevaba a la ruina y mis hoteles en las avenidas de lujo me hacían absurdamente rico, más o menos como lo que sucede hoy en día con Internet, en donde casi todo es igual de ridículo. No obstante, llegado ese punto solo había una manera de continuar jugando; tenía que devolver parte del dinero y los terrenos -que había ganado- a mis oponentes.
- Esta es justamente la situación actual Europa con Grecia, España, Italia y los demás miembros débiles de la Euro zona.
El juego de la Euro zona, durante la ultima década, ha permitido un florecimiento sin precedentes en Alemania y en otros países ricos. El Euro les brindó una taza de intercambio virtualmente competitiva permitiéndoles exportar sus bienes a los países más pobres, que de otra manera no hubiesen tenido acceso a estos. Así pues, las naciones periféricas podían aceptar dichos bienes, ya que el ser “miembros” les ofrecía la opción a créditos baratos y una moneda sobre valorada. Todos se sentían prósperos, aún cuando Alemania seguía sumando dividendos y los otros sumando deudas.
Claro estaba que este des-balance no podía ser para siempre. Los fundadores del Euro pensaron que, de alguna mágica manera, las economías dispares se llegarían a parecer bajo una moneda común. No fue así. Los países más pobres no utilizaron sus créditos para la inversión, sino para el consumo. Muy lejos de parecerse a Alemania, se alejaron cada vez más; la producción griega -por ejemplo- cayó un 35% frente a la alemana en tan solo una década.
Nadie, mucho menos los grandes entusiastas del Euro, advirtió este problema que se les venía encima. Se le prometió paz y prosperidad al electorado europeo y, por lo visto, lo parecían haber obtenido, en cuyo caso ¿por qué querría alguien perturbar dicha paz con verdades incomodas?
Ningún líder confrontó a los países menos eficientes a cambiar sus prácticas laborales, su productividad, sus estrategias de inversión y sus servicios públicos. En el norte, los países ricos, Alemania principalmente, nunca le dijo a su población que el precio por tener mercados cautivos y pobres en el sur sería el tener que subsidiarlos, posiblemente a plazo permanente, si estos dejaban de -o ya no podían- pagar.
Finalmente, la burbuja explotó con la crisis financiera del 2008, desde entonces todas las contradicciones del Euro se han vuelto miserablemente evidentes. El modelo de una moneda compartida sin instituciones compartidas, sin un banco central que la respalde y sin una responsabilidad compartida por la deuda que otros países puedan adquirir, es, como muchos expertos advirtieron, una falla mortal. Las consecuencias están siento terribles: desempleo por millones -hasta con un 50% entre la población joven, cortes insostenibles implantados por estados empobrecidos, negocios que colapsan, una banca al borde de la bancarrota y -sobre todo- desesperación humana.
El hecho que que los arquitectos del Euro se nieguen ahora a aceptar sus errores es un abuso. Aún peor es el hecho de que sus líderes se nieguen a ponerse de acuerdo en soluciones reales a medida que la catástrofe se desarrolla. La respuesta internacional a Grecia, encabezada por Alemania junto con el FMI y el Banco Mundial no tiene sentido. Grecia ha sido obligada a recortar el tamaño del estado, recortar sus pensiones, recortar sus salarios y recortar sus necesidades domésticas, todo esto al mismo tiempo que se esperaba su crecimiento para que pudiese pagar sus deudas.
Esto es como quitarle a un jugador de Monopoly todas sus casas y sus hoteles y exigirle que sea capaz, al mismo tiempo, de producir lo suficiente como para mantenerse en el juego. ¡Es imposible! Y ahí están las últimas cifras en economía para demostrarlo.
La deuda de Grecia era de un 110% de su PIB cuando estalló la crisis, después de cinco años de cortes salvajes, con la intención de reducir gastos, el FMI espera que alcance un 160% de su PIB en 2013. Que no se admire nadie con la ira de los griegos y el hecho de que han amenazado con dar la espalda a sus deudas. Quieren quedarse con el Euro pero no quieren pagar sus cuentas. Los alemanes, por otro lado, son obstinados: si Grecia se niega a cumplir con sus acuerdos, se tendrá que marchar de la zona, a cualquier costo. Este punto ha de ser resuelto en las próximas cinco semanas, justo después de que Grecia tenga sus elecciones finales, ya que después de ese punto no les quedará dinero alguno. De repente la salida de Grecia se ha vuelto muy real y cercana.
Las naciones ricas nunca imaginaron tener que dar apoyo indefinido a las naciones pobres y las naciones pobres nunca imaginaron ser aplastadas por sus deudas. Ahora se enfrentan a una decisión: apoyarse las unas a las otras en una unión inevitablemente menos democrática y menos fiscal, o separarse y aceptar el caos y el empobrecimiento que dicha separación dará como resultado. Lo cierto es que este torbellino no puede continuar. La decisión está, mayoritariamente, en manos alemanas.
- Si aprecian el juego y quieren que los demás jugadores permanezcan en la mesa, entonces tendrán que empezar a devolver algunas de las cartas, tal como me tocó hacer a mi.
Si lo que nos interesa es almacenar grandes cantidades de información a bajo costo, entonces no hay duda que un disco duro convencional (HDD) es la opción más indicada, sin embargo las velocidades de lectura y escritura no son las mejores. Están, por otro lado, los disco de estado sólido (SSD) que ofrecen velocidades trepidantes, tanto para lectura como para escritura, pero -claro- son mucho más caros. No obstante, nos queda una tercera alternativa; la memoria RAM.
Con el rápido avance de la tecnología, se ha convertido en habitual ver máquinas con cada vez más memoria RAM y con precios cada vez inferiores, relativamente. Utilizar la memoria RAM para almacenar datos resulta en velocidades muy por encima, incluso, que de los discos SDD y sin los costos adicionales que implicaría un disco SSD. Es aquí donde podemos empezar a hablar de discos RAM.
Un disco RAM almacena todo lo que en él se escriba en la memoria RAM (como su nombre lo indica) que es, a su vez, memoria volátil y que se perderá al apagar el equipo, aunque para esto último también existen soluciones. Los discos RAM tampoco son para cualquiera y -sin duda- su aplicación ideal es en entornos en donde haya que procesar grandes cantidades de información en el menor tiempo posible, lo cual se logra sin tener que escribir y leer de un disco convencional. Básicamente, este incremento en la velocidad viene derivado de dos cosas:
- La CPU puede acceder directamente a cualquier información que esté en RAM, sin tener que pasar primero por ningún bus de datos. Esto, claro, es imposible con un disco HDD o incluso con un disco SDD, ya que ambos dependen del bus del que disponga el equipo.
- El tiempo de búsqueda, es decir, el tiempo que se tarde en encontrar la ubicación de un determinado archivo en memoria o si este existe en un determinado medio físico, es prácticamente nulo.
Pues bien, hacer uso de esto es muy fácil en los sistemas operativos (Linux) actuales y se basa en el controlador de sistemas de archivos tmpfs (tmpfs está soportado oficialmente en todos los kernels de Linux desde la versión 2.4 en adelante). Para Windows existen herramientas desarrolladas por terceros que son capaces de ofrecer este tipo de solución.
Si, por ejemplo, nos referimos a Ubuntu, este viene con un disco RAM activado por defecto y que se puede utiliza en cualquier momento para mover información o realizar tareas de proceso como las antes mencionadas. Este disco está montado en la ruta: /dev/shm/ En cualquier caso, esta opción no es la más adecuada, ya que el sistema no impone un límite al tamaño de dicho disco, con lo cual si se sobrepasa su capacidad, entonces el sistema paginará parte de su contenido a un archivo de paginación (swap), que, de nuevo, no es otra cosa que un archivo físico en un disco duro, perdiendo así la velocidad de escritura y lectura, lo que nos lleva nuevamente al punto inicial. También es posible que se produzcan volcados de memoria y el equipo se cuelgue, perdiendo así todo cuanto se tenía en RAM.
La mejor opción es limitar el tamaño máximo del disco RAM, de modo que no se produzcan errores ni pérdidas en nuestra información. En Ubuntu (tanto como en Debian, Crunchbang, etc.) se puede hacer fácilmente creando y montando la unidad del tamaño que nos haga falta:
sudo mkdir /tmp/discoram
sudo mount -t tmpfs -o size=512M tmpfs /tmp/discoram
El tamaño del disco se puede variar al tamaño que se quiera con el parámetro size.
También se puede cambiar el tamaño del disco sobre la marcha, aunque no es muy recomendable. Esto se puede hacer con:
sudo mount -o remount -o size=1024M /tmp/discoram
Finalmente, cuando ya no haga falta tener este espacio alojado en RAM, se puede desmontar con:
sudo umount /tmp/discoram
Cada vez me sorprendo más y más; España es -sin duda- un país curioso. Leyendo artículos y demás, se podría pensar que los países en donde las cosas van peor o donde la corrupción está en plano auge, son siempre los países de allá, los del tercer mundo, sin embargo aún queda en esos países un poco de respeto por la gente, por las familias, por una vida digna.
España lleva ya unos años en crisis y -claro- eso ha causado muchos problemas de impagos, generalmente por gente que ha comprado casas o pisos y que ahora no tiene como hacer frente a las deudas, por lo general con los bancos, claro que también casos de familias que simplemente se han quedado en el paro y que -del mismo modo- no tienen como afrontar las mensualidades.
Ahora bien, lo que me admira es lo siguiente; según la constitución española (Capítulo III, de los principios rectores de la política social y económica, artículo 47):
Todos los españoles tienen derecho a disfrutar de una vivienda digna y adecuada. Los poderes públicos promoverán las condiciones necesarias y establecerán las normas pertinentes para hacer efectivo este derecho, regulando la utilización del suelo de acuerdo con el interés general para impedir la especulación.
La comunidad participará en las plusvalías que genere la acción urbanística de los entes públicos.
Pues bien; está ley parece no aplicarse en el caso de que el acreedor sea un banco, me explico: supongamos que yo alquilo un piso en España y pagando un alquiler de 800 euros al mes (por los cuales alguien se tendrá que haber hipotecado en su momento y que depende de dicho pago para llegar a fin de mes). En cualquier momento yo podría dejar de pagar dichas mensualidades y a pesar de haber firmado un contrato y un compromiso por el alquiler, el dueño no puede hacer absolutamente nada al respecto, bueno, si; me puede llevar a juicio, no obstante es un juicio que puede tardar meses, incluso años, como en la mayoría de los casos. He visto muchos casos de gente, trabajadores como cualquiera, que se han hipotecado -por cosas de la vida- y han puesto ese piso hipotecado en alquiler y de pronto el inquilino ha decidido suspender los pagos, dejando a al arrendatario en la ruina total, literalmente. Estos casos llevan años y años intentando sacar al inquilino que no paga, pero la “justicia” no hace nada. Lo peor de todo esto es que el inquilino -el que ha suspendido los pagos- puede incluso demandar al propietario por acoso, por molestar, por una cantidad de cosas. De nuevo, los años pasan y la ley no hace absolutamente nada en estos casos.
Ahora el caso opuesto, gente -humilde- que se ha hipotecado y que vive en el piso hipotecado y que, de nuevo, por cosas de la vida, se han quedado en el paro. En este caso, si el piso le pertenece a un banco, entonces el banco buscará lograr un desahucio, sacar al inquilino que no paga (que no puede pagar) y rematar el piso. Estos casos se resuelven enseguida, en menos de lo que canta un gallo, a lo mucho 3 semanas un juez analiza el caso y dictamina la sentencia. En menos de un mes, la familia es -por orden de la justicia española- expulsada de su casa y en este caso no se puede hacer nada; es la misma policía la que viene a hacer el “trabajo”.
Entonces, no hace falta ser un genio para darse cuenta de como son las cosas en España. Las instituciones financieras son los reyes y las reinas de este juego y el pueblo -el que genera los ingresos- es el plebeyo. Y luego siempre están los casos de multimillonarios -estafadores- que están por ahí viviendo como jeques árabes u otros que si que han sido filtrados por la “justicia” pero que son de nuevo puestos en libertad pagando las fianzas, con el dinero de los estafados.
El pueblo no debe temer a sus gobiernos, es el gobierno quien debe temer al pueblo.

