Thursday, August 29, 2013

Sesiones web en alta disponibilidad

En este post voy a tratar de explicar con una demostración de concepto, como dotar de alta disponibilidad a las sesiones de una aplicación web.

 Debido a mis limitaciones técnicas, voy a utilizar lo siguiente:
  •  nginx como balanceador web 
  •  php como lenguaje de programación 
  •  apache como servidor web 
  •  memcached,  la estrella en todo esto. 

todo esto sobre Debian Wheezy.

Cuando se tiene una granja de servidores web para una aplicación, se requiere que la información almacenada en la sesión de usuario se mantenga y pueda ser accedida por cualquiera de los servidores, incluso, cuando alguno de ellos falla. Existen varias técnicas, algunas más complicadas que otras. Yo voy a hablar de como hacerlo con memcached.

Escenario

 El escenario descrito como bloques funcionales será el siguiente:
  •  Un balanceador web (nginx) 
  •  Dos servidores web (apache + php) 
  •  Tres instancias de memcached 

El blanceador (nginx) tendrá como servidores de backend a los dos apaches que son los que alojarán el código php del supuesto sitio web. Para efectos de esta demostración de concepto, todos estos bloques funcionales estarán corriendo en la misma máquina :) Espero que esto no lleve a confusión.

Comenzamos con la instalación y configuración de los bloques funcionales.

Balanceador web (nginx) 

Instalamos nginx de la siguiente manera:
# aptitude install nginx


 Nos vamos al directorio /etc/nginx/sites-available y creamos el archivo mem-test que tendrá la configuración de nuestro balanceador. Este es el contenido del archivo:
upstream mem-test {
                   server 127.0.0.1:8081;   
                   server 127.0.0.1:8082;

}

server {
      listen 8080;
      location / {
                  proxy_pass http://mem-test;
      }
}


Como se aprecia, voy a tener dos servidores web escuchando en los puertos 8081 y 8082. Será mi "granja" que después configuraré. La sección siguiente le dice a nginx que escuche en el puerto 8080 (mi blanceador) y que todo lo que llegue lo pase a los servidores descritos arriba.

Nos vamos al directorio /etc/nginx/sites-enabled, creamos un link simbólico que apunte al archivo creado
# cd /etc/nginx/sites-enabled
# ln -s /etc/nginx/sites-aviable/mem-test

y borramos el link "default".

Listo, ya tenemos nginx configurado como balanceador, nos queda arrancarlo:
# service start nginx

No deberían salir errores si se siguieron los pasos descritos.

Servidores web (apache + php) 

Instalamos apache y php de la siguiente manera:
# aptitude install apache2 libapache2-mod-php5

Configuramos dos virtualhosts en apache añadiendo
NameVirtualHost *:8081
NameVirtualHost *:8082
Listen 8081
Listen 8082

al archivo /etc/apache2/ports.conf y creamos dos archivos de configuración llamados server01 y server02 en /etc/apache2/sites-available. Estos son los que yo creé:
server01
<VirtualHost *:8081>
        ServerAdmin webmaster@localhost

        DocumentRoot /var/server01
        <Directory />
                Options FollowSymLinks
                AllowOverride None
        </Directory>
        <Directory /var/server01>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride None
                Order allow,deny
                allow from all
        </Directory>

        ErrorLog ${APACHE_LOG_DIR}/error.log

        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel warn

        CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>


server02
<VirtualHost *:8082>
        ServerAdmin webmaster@localhost

        DocumentRoot /var/server02
        <Directory />
                Options FollowSymLinks
                AllowOverride None
        </Directory>
        <Directory /var/server02>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride None
                Order allow,deny
                allow from all
        </Directory>

        ErrorLog ${APACHE_LOG_DIR}/error.log

        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel warn

        CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Creamos los directorios /var/server01 y  /var/server02 que alojarán las páginas de nuestros sitios web
# mkdir /var/server01 /var/server02

Activamos los sitios:
# a2ensite server01 server2

Memcached 

Instalamos memcached y el soporte de php para memcache
# aptitude install memcached php5-memcache

Creamos los tres archivos de configuración de las instancias de memcached
cp /etc/memcached /etc/memcached_inst01.conf
cp /etc/memcached /etc/memcached_inst02.conf
cp /etc/memcached /etc/memcached_inst03.conf

En mi escenario, estos son los puertos en los que escuchan las diferentes instancias de memcached:
  • inst01: 11211 
  • inst02: 11212 
  • inst03: 11213 


Eso se hace modificando la línea donde dice "-p" en cada archivo de configuración y colocando el valor correspondiente.

Arrancamos memcached
/etc/init.d/memcached start
Starting memcached: memcached_inst01.
Starting memcached: memcached_inst02.
Starting memcached: memcached_inst03.

Podemos comprobar que están corriendo con un ps.

php5-memcache 

Para que php use memcache para almacenar las sesiones, hay que realizar lo siguiente:
En el archivo /etc/php5/apache2/php.ini colocar:
session.save_handler = memcache
session.save_path = "tcp://127.0.0.1:11211,tcp://127.0.0.1:11212,tcp://127.0.0.1:11213"

y en el archivo /etc/php5/apache2/conf.d/20-memcache.ini añadir:
memcache.session_redundancy=4

Nota muy importante, el valor de memcache.session_redundancy debe ser igual al número de instancias de memcached +1.

Reiniciamos el apache:
# service apache2 stop
# service apache2 start

Solo falta escribir un código de prueba. En cada uno de los DocumentRoot de los virtualhosts, creamos un archivo llamado index.php como el siguiente para comenzar:
<?session_start() ?>
<html>
<head>
        <title>Server01</title>
</head>
<body>
Server01
<? if(empty($_SESSION['contador'])) {?>

<p>El contador est&aacute; vac&iacute;o</p>
<? }else {?>
<p>Valor actual del contador: <? echo $_SESSION['contador'];?></p>
<p>Sumamos 1 al contador</p>
<? $_SESSION['contador'] = $_SESSION['contador'] + 1;}?>
</body>
</html>

Hay que tener en cuenta que cada index.php debe reflejar el nombre de su respectivo servidor virtual.

Ahora, con cualquier navegador (yo usé lynx) podemos probar con la URL
http://localhost:8080

y recargamos la página varias veces.

Esta prueba debe mostrar _siempre_ que la variable "contador" está vacía lo cual es lógico. Lo único que debería variar es el nombre del servidor, que debe alternarse entre server01 y server02 con lo que sabemos que el balanceador está funcionando.

Una vez confirmado esto, modificamos el index.php de server02 para que quede de esta manera:
<? session_start() ?>
<html>
<head>
        <title>Server02</title>
</head>
<body>
Server02
<? if(empty($_SESSION['contador'])) {?>
<p>El contador est&aacute vac&iacute;o</p>
<? $_SESSION['contador'] = 1;
 }else {?>
<p>Valor actual del contador: <? echo $_SESSION['contador'];?></p>
<p>Sumamos 1 al contador</p>
<? $_SESSION['contador'] = $_SESSION['contador'] + 1;}?>
</body>
</html>

Al recargar la URL debemos observar como el contador comienza a incrementarse después de haber contactado a server02.

Para probar que se mantienen las sesiones al ocurrir un fallo, procedemos a parar las instancias de memcached teniendo en cuenta que hay que dejar el menos una corriendo.
# /etc/init.d/memcached stop inst01

Al recargar la URL deberíamos observar que el contador se sigue incrementando demostrando así que tenemos alta disponibilidad con las sesiones web.

Esto es solo una demostración de concepto pero se evidencia la flexibilidad y redundancia de memcached para guardar y mantener la información de las sesiones web.

Tuesday, August 13, 2013

El día de mi suelta

El día de la suelta para un alumno piloto es un gran día, es el momento en el cual sus instructores estiman (ilusos ellos) que el alumno tiene las habilidades mínimas necesarias como para no matarse viajando solo en un avión.

Es un día especial donde la emoción y el susto se combinan para que tengas una sensación que nadie ha podido definir aún.

Este es el relato de mi día de la suelta.

Me había programado para volar el sábado temprano (9:00 a.m) porque en verano me gusta volar a primera hora de la mañana, así me evito turbulencias producidas por térmicas y el avión tiene mejor performance (aire más frío).

Volar a primera hora también tiene sus contras, tienes que pararte más temprano, tienes que ir con prisas para llegar a la oficina ARO de Cuatro Vientos (abren a las 8:30) y tienes que ser Usain Bolt para llegar rápido a la plataforma de la escuela que queda "llegando a Coslada" para ver si no te agarra el "atasco" en el punto de espera que parece la A6 en hora pico.

Para palear un poco estos contras, lo que hago es meter el plan de vuelo el día anterior por la tarde, así llego directo al control de seguridad el día del vuelo y me ahorro un poquito de tiempo (solo un poquito).

Pues bien, el viernes en la tarde veo la página de programación de la escuela que, aunque la información que sale ahí no es oficial sino hasta las 8 de la noche, a las 3 de la tarde es muy probable que esa información ya sea la definitiva (iluso pequeño saltamontes).

A eso de las 4 de la tarde y por "no dejar", reviso de nuevo la página de programación de la escuela y .... oh sorpresa, me habían cambiado al instructor y ahora decía "check". Por supuesto, puse cara de "ponchao", eso de check no lo había visto nunca y pensé que debían ser las nuevas políticas de la escuela que ahora te hacen chequeos teóricos frecuentemente.

No me parece mal, así te obligan a repasar la teoría siempre.

Pues bien, con eso en mente salgo de la oficina hacia Cuatro Vientos (LECU de ahora en adelante) a meter mi plan de vuelo para el sábado un poco preocupado porque, para que coloquen en la programación que me van a hacer un "check", pues debe ser importante, así que ya me veía yo llegando a la casa a estudiar y perderme las finales del viernes del mundial de natación Barcelona 2013.

Llego a LECU, estaciono delante de la terminal y vuelvo a intentar verificar  la programación de la escuela, no fuese a ser que cambiara de nuevo. En eso recibo una llamada, es este nuevo instructor que me han colocado diciéndome que me va a hacer un chequeo y que me prepare un routing El Alamo, Illescas, me parece raro, muy corto. Le pido que me confirme que es El Alamo, Illescas y nos devolvemos a Cuatro Vientos y me dice que si y que ponga la EOBT a las 9:15 locales y que me esperará en operaciones a las 8:30.

Sin problemas, me voy a la oficina ARO, meto mi plan de vuelo, consulto NOTAMS para el sábado y listo, sale mi plan de vuelo aprobado por la impresora y me voy para mi casa.

El camino de vuelta fue una elucubración constante, el routing era muy corto, seguro que era para evaluarme el timing en los puntos de referencia... uffff me toca afinar bastante en el cálculo de tiempos, y siendo tan corto, seguro me iba a freir con teoría....

Pienso también que.... y si es la suelta? OMG!!!!! .... no, no creo, estoy muy "pichón" pero igualito "huele mal".

Llego a las casa con "cara de circunstancias", mi esposa me pregunta que qué me pasa y le cuento lo del "check". Ella me dice que no me preocupe, que me lo tome con calma, que siempre me tomo las cosas muy a pecho. Tiene razón pero cuando llevas eso en el "firmware" poco se puede hacer....

Total que me pongo manos a la obra, saco mis "macundales" y me pongo a hacer el routing. Es tan pero tan corto que solo alcanzo a colocar un punto intermedio en cada tramo para llevar el timing... pienso que aquí está la "trampa", ve van a joder con eso.

Termino de hacer mis garabatos sobre la carta 1:500000, agarro el manual del avión y comienzo a leerme los fallos de motor, los fuegos, velocidades características, etc, etc.

Mi esposa, al verme así, me dice que me va a hacer la cena, que no me preocupe y siga estudiando :)

Termina la natación (damn it!!!! no vi casi nada), termino de cenar y agarro el "análisis de maniobras" que seguro me pone a hacer mil pérdidas y tres mil fallos de motor... "mínime!!!!!!"

Ya preocupado por la hora, me voy a dormir temprano para estar "despierto" al día siguiente.

Suena el despertador y partida!!!!!!! a bañarme, desayunar, sacar la meteo y los NOTAM's y "ráspalo" pa' LECU.

Llego a la terminal (casi vacía), paso el control de seguridad y "rumbo a Coslada".

Cuando llego a la plataforma de la escuela, veo al avión que me toca con las puertas abiertas, full flaps.... que raro.... será que me equivoqué de avión?? Bien bueno pues.....

Entro a la oficina y está extrañamente "llena", dos instructores, tres alumnos (WTF??!!). En fin, se presenta mi instructor (primera vez que lo veo), confirma mi nombre y me dice, "siéntate ahí"... listo, comienza "el parto".

Me pide certificado médico, tarjeta de alumno, plan de vuelo, meteo, plan de vuelo operacional, ruting, NOTAM's, nombre y pedigree de la mascota de mi hermana... (ok, se me fue la mano ;) ).

Me bombardea de preguntas e intento responderlas lo mejor que puedo y cuando terminamos me dice: vamos a avolar..... ajá!!!! aquí está la trampa!!!!! no he hecho la carga y centrado ni la exterior!!! pues nada, se lo digo al instructor y me dice que la exterior la hizo el y la hoja de carga y centrado también.

Lo miro con desconfianza y le insisto, "pero seguro"? y me responde el con mirada de "ya estamos con el mequetrefe este", si, ya lo hice yo, vámonos ya.

Ok, con esa capacidad de convencimiento, nos dirigimos al avión, doy una "ojeada rápida" por si las moscas y comenzamos con la checklist.

Todo perfecto, me dispongo a rodar y el instructorme dice "mío el avión", perfecto, agarra el avión como si fuese una bicicleta, lo saca de plataforma y me lo da. Me dice que me apure para que no nos agarre "el atasco". Bien, pruebo mis frenos y listo, el primer regaño, "no frenes así, no estás probado el ABS", ok, lo tendré en cuenta (uffff bonito comienzo)..

Seguimos hasta el punto de espera de la 28 y el instructor se pone a hablarme del anti skid..... fine.... a ver si se me olvidan los chequeos de brújula , direccional, bastón y bola.... le interrumpo diciéndole que voy a hacer las pruebas y me dice que ok...

Ya en el punto de espera con briefing's y prueba de motor lista, nos autorizan a despegar por la 28, viento en calma (muy bien!!!!).

Estando en viento en cara me dice el instructor que vamos a hacer 2 tomas y despegues, que hable con la torre en viendo en cola.... ok, perfecto, la torre nos autoriza y uffff, a ver como me sale esta toma, las últimas con full flaps me han salido un poco flojas, en cambio, con dos puntos de flaps, esas si me salen chéveres.

Pues bien, ya con toma asegurada y en la cabecera de la 28 con las que te conté de corbata, intento hacer una toma "buena".... uffff un poco dura... ya estamos.... sin embargo el instructor me dice que la toma bien, pero que tengo que rotar a 55 KIAS y no a 60 como siempre he practicado, pero bueno, que lo tenga en cuenta.

Seguimos con la segunda toma y la torre me dice que alargue el viento en cola y autoriza a un tráfico, que estaba en el punto de espera, a despegar.

El tráfico se demora un poco y el instructor me dice: "ves? cuando digas listo salida es listo salida porque haces esperar a los demás tráficos".

Entendido... ya me estaba poniendo nervioso porque ese viento en cola estaba llegando a Vallecas ( no es cierto ;) ) cuando veo que el tráfico despega. Viro a base y la torre nos autoriza a aterrizar.

Como el final fue "largo", me dió tiempo a colocarme bien y a "pensar mucho" en esa toma.... no meter flap's tan pronto que quedaba bastante tiempo, calma...

Ya con toma asegururada y full flap's presento el avión, comienzo la recogida tratando de que esta toma si fuese "buena".... suena la bocina de pérdida y pack, toma suave... coño!!! seguro tomé con 2 puntos de flaps... Verifico los flap's y no, están en full.... pues nada, limpiar el avión, full gases y nos vamos!!!.

Al menos esta toma si había salido como a mi me gusta.

Total que nos dirigimos a W, le comento como voy a hacer el routing, preparo frecuencias, carta, etc, notificamos en W, ponemos rumbo al Alamo y "saludamos" en aire-aire.

El instructor sigue hablándome no se si para distraerme o porque el es así, al menos el vuelo sería "entretenido".

Ya rumbo a Illescas comenzaron las "gracias", fallos de motor, preguntas trampa a ver si sabía en donde estaba pero lo más importante, consejos de "aviación práctica", no la que sale en los libros, la que me va a salvar la vida, cosa que se agradece mucho.

Así transcurrió el vuelo, más fallos de motor, más consejos prácticos, más fallos de alternador, batería, etc etc etc (creo que falló todo lo que tenía que fallar!!!!!).

Ya entrando en al circuito de LECU, escucho en frecuecia la frase "toma intermedia para suelta de alumno"..... de otros tráficos :( dos que recuerde.

Viendo que me quedaba mucho tiempo, le pregunté si esta era toma final o podíamos hacer más tomas y despegues, el me dice que llevará las comunicaciones y que yo me centre en el avión, pues bien, cada vez que el hablaba con la torre yo no escuchaba nada (medio fallo de radio!!!! lo que faltaba!!!!). Le dije que no lo escuchaba cuando hablaba con la torre y el me contestó de lo más tranquilo: "si, yo tampoco te escucho a ti cuando notificas, tengo que verte para saber que estás diciendo (WTF!!!!!!!!!???????????)

Seguimos en aproximación, tomo y le pregunto de nuevo "qué hacemos? plataforma?". No me contesta, liberamos pista, torre nos pasa con rodadura, el instructor sigue hablando con la controladora y yo nada que escucho, (fuck!!!!). Le insisto de nuevo " ya?, no vamos a hacer tomas y despegues?" y el me responde con : "quieres volar solo"? (WHAT!!!!!!!!) - eehhhmmmm mmmmm si... pero..... - y me sigue diciendo: "bueno, ahora llegamos a plataforma y te vas tu solo.... (OMFG!!!!!!!!!!!!!!!!!).

Seguimos a plataforma y antes de llegar a los caribou's me dice, mío el avión, hace un 360 y me dice, "lo agarras desde aquí, aprovecha el día que está muy bueno y no vengas antes de una hora" (GOOOOOOOOOOOOD!!!!!)

Por supuesto, no tenía routing de nada aparte del que había preparado así que le digo, bueno, a ver dónde me voy ahora, el me sugiere Toledo y me parece bien.

Me gusta mucho Toledo y ya la había sobrevolado una vez y es espectacular, así que con autorización, hasta punto de espera de la 28 y a Toledo....

Creo que todavía no me daba cuenta de que era mi suelta, estaba pendiente de checklist's, la ruta que iba a seguir, altitud, tráficos, etc... ya en W y en frecuencia aire-aire notifico que voy al Bosque de Batres, 3000 ft, al ratico notifican 2 tráficos que están cerca del bosque de Batres y que van a S.

Desde operaciones de la escuela "advierten" que estoy en mi suelta y que si pueden, amablemente, subirse 500 ft =) Los tráficos aceptaron sin problemas (desde aquí mil gracias por facilitarme las cosas), sin embargo, ya los tenía a la vista así que los podía evadir.

Ya con el Bosque de Batres a mi izquierda, notifico que voy rumbo sur a Recas, 3000 ft. Que sorpresa, otro tráfico estaba sobre Recas a 3000 ft y rumbo a Toledo, bien bueno pues, hoy es el día de ir a Toledo me dije :)

Decido entonces notificar cuado llegue a Lomichar, así saben que el rookie de la suelta anda por ahí. Escucho a otro tráfico sobre Chozas de Canales y creo recordar que iba hacia Casarrubios, perfecto, más gente para la fiesta.

Abro los ojos lo más que puedo y comienzo a hacer el scan del cielo a ver si aparece "algo"... nada.... ya sobre Lomichar vuelvo a notificar y escucho a mi precedente sobre Olias del Rey... bien, vamos en caravana...

Como ven, de disfrutar poco, siempre pendiente de los tráficos, la altitud, el mapa, los pueblos.... ufffff.

Por fin en Recas, notifico y mi precedente dice que está en Toledo y que se sube a 4500 ft, bien, parece que podré orbitar sobre Toledo sin problemas...

La cosa se relaja un poco sobre Olías del Rey, ya tenía a Toledo en el morro y nadie se había reportado por la zona, hora de descansar orbitando sobre el oeste de Toledo..... el casco histórico es impresionante desde 3000 ft... esta es parte de la recompensa después de haber sufrido a Adsuar.

No se cuantas vueltas di al oeste de Toledo, creo que no me canso de verla :), para asegurarme el disfrute reporté que iba a estar orbitando sobre Toledo, así sabrían que había alguien por ahí.

Miré la hora y decidí regresarme, justo en ese momento se reporta un tráfico que venía de Recas a Toledo, no se si se había reportado antes, yo estaba muy "ocupado" :)

Notifiqué que abanonaba Toledo rumbo Olías del Rey y me aparté un poco a la derecha por si las moscas.

El tramo de vuelta fue tranquilo, la frecuencia estaba callada y fue ahí donde me di cuenta que estaba volando yo solo y que era el día de mi suelta.