Tomcat 7.X persistencia de sesion HTTP en Cluster de MongoDB

En este articulo voy a describir los pasos necesarios para configurar la persistencia de sesión HTTP en un Cluster de MongoDB utilizando Tomcat 7.X como contenerdor Web, cabe destacar que es una solucion experimental, no valida para un entorno de producción.
En muchos entornos productivos se suele persistir la sesion en base de datos o en caches distribuidas, en términos generales la persistencia en bbdd suele ser muy performante, pero en caso de problemas suele afectar muy seriamente al servicio, esta es la motivación principal para probar un método alternativo de persistencia.
MongoDB ofrece un esquema de replicacion muy interesante y simple, la inserción de documentos en la base de datos se puede hacer en diferentes modos, estos y otras características de MongoDB lo convierte en un motor de persistencia muy atractivo.

Este artículo parte de la base que el MongoDB ya esta instalado, el cluster de MongoDB lo componen 3 instancias en el mismo nodo, este articulo esta dividido en 5 secciones, las dos primeras describen los pasos de configuracion del cluster MongoDB como del Session Manager en Tomcat.

1) Configuracion del cluster de MongoDB

1-a) Inicio de las 3 instancias mongo.

mongod --port 27017 --dbpath /home/nose/mongodb/db1 --replSet rs0 --smallfiles --oplogSize 128 --rest
mongod --port 27018 --dbpath /home/nose/mongodb/db2 --replSet rs0 --smallfiles --oplogSize 128 --rest
mongod --port 27019 --dbpath /home/nose/mongodb/db3 --replSet rs0 --smallfiles --oplogSize 128 --rest

1-b) Configuracion de la replica, para ello nos conectamos al primer miembro del cluster.

mongo --port 27017

rsconf = {
           _id: "rs0",
           members: [
                      {
                       _id: 0,
                       host: "[IP]:27017"
                      }
                    ]
         }

rs.initiate(rs)
rs.add("[IP]:27018")
rs.add("[IP]:27019")
rs.status()

NOTA: Debes remplazar [IP] por tu IP local.

* También se puede consultar el estado de la instancia mongo vía http, en mi caso

http://localhost:28017/

2) Generación del Valve y Session Manager para Tomcat.

He partido del proyecto https://github.com/dwelch2344/mongo-tomcat-session-manager , lo importe en mi entorno eclipse para realizar algunos ajustes para soportar nodos secundarios en el string de conección y soportar Tomcat 7.0.42.

2-a) Desplegar librerías.
He utilizado el conector java de MongoDB, exactamente la versión 2.9.3, la librería mongo-java-driver-2.9.3.jar la debes desplegar en $TOMCAT_HOME/lib.
Luego la libreria del "mongo-tomcat-session-manager" la exportas de eclipse a $TOMCAT_HOME/lib.

El conector java de MongoDB se puede descargar de http://central.maven.org/maven2/org/mongodb/mongo-java-driver/

2-b) Configurar el Session Manager, he utilizado la siguiente configuración  en el fichero context.xml

<?xml version='1.0' encoding='utf-8'?>
<Context>
    <Valve className="co.ntier.mongo.tomcat.MongoSessionTrackerValve" />
    <Manager className="co.ntier.mongo.tomcat.MongoSessionManager" 
             serverAddress="localhost:27017,localhost:27018,localhost:27019" 
             databaseName="sessions" 
             />
</Context>

2-c) Reiniciar el servicio Tomcat

cd $TOMCAT_HOME/bin
./startup.sh

Si todo funciona correctamente en el log catalina.out deberías ver una entrada similar a la siguiente:

INFO: Connected MongoManager to localhost:27017,localhost:27018,localhost:27019/sessions (slave: false; TTL: 1800000)

3) Validar el entorno Tomcat, para ello utilizamos una aplicación de ejemplo que viene con Tomcat.

http://localhost:8080/examples/servlets/servlet/SessionExample


4) Validar la existencia de la sesión en la base de datos de MongoDB, para ello entramos en el primer nodo del cluster de mongo.

mongo --port 27017

rs0:PRIMARY> show databases
rs0:PRIMARY> use sessions
rs0:PRIMARY> show collections

rs0:PRIMARY> db.sessions.find()
{ "_id" : "652a53d4-aae5-472c-a716-cfea07f21761", "data" : BinData(0,"rO0ABXcIAAABQEpZgudzcgAOamF2YS5sYW5nLkxvbmc7i+SQzI8j3wIAAUoABXZhbHVleHIAEGphdmEubGFuZy5OdW1iZXKGrJUdC5TgiwIAAHhwAAABQEpZgudzcQB+AAAAAAFASlmC53NyABFqYXZhLmxhbmcuSW50ZWdlchLioKT3gYc4AgABSQAFdmFsdWV4cQB+AAH/////c3IAEWphdmEubGFuZy5Cb29sZWFuzSBygNWc+u4CAAFaAAV2YWx1ZXhwAHEAfgAHc3EAfgAAAAABQEpiw9l0ACQ2NTJhNTNkNC1hYWU1LTQ3MmMtYTcxNi1jZmVhMDdmMjE3NjFzcQB+AAQAAAAKdAABMXQAATF0AAE3dAABN3QAATh0AAE4dAABNXQAATV0AAE2dAABNnQAATN0AAEzdAACMTB0AAIxMHQAATR0AAE0dAABOXQAATl0AAEydAABMg=="), "lastmodified" : NumberLong("1375637521374") }

NOTA: El _id del documento (rojo) es la identificacion de la sesión, siendo el mismo valor de la cookie JSESSIONID

5) Validación del cluster MongoDB, simplemente haciendo un kill -9 [PID] de la instancia primaria del cluster, nos sirve para validar como el cluster negocia una nueva instancia primaria y como el Session Manager recupera y actualiza correctamente la session previamente almacenada.

rs0:PRIMARY> db.sessions.find()
{ "_id" : "652a53d4-aae5-472c-a716-cfea07f21761", "data" : BinData(0,"rO0ABXcIAAABQE+5AglzcgAOamF2YS5sYW5nLkxvbmc7i+SQzI8j3wIAAUoABXZhbHVleHIAEGphdmEubGFuZy5OdW1iZXKGrJUdC5TgiwIAAHhwAAABQE+5AglzcQB+AAAAAAFAT7kCCXNyABFqYXZhLmxhbmcuSW50ZWdlchLioKT3gYc4AgABSQAFdmFsdWV4cQB+AAEAAAcIc3IAEWphdmEubGFuZy5Cb29sZWFuzSBygNWc+u4CAAFaAAV2YWx1ZXhwAXNxAH4ABgBzcQB+AAAAAAFAT7kCCXQAJDY1MmE1M2Q0LWFhZTUtNDcyYy1hNzE2LWNmZWEwN2YyMTc2MXNxAH4ABAAAAAF0AAExdAABMQ=="), "lastmodified" : NumberLong("1375727059469") }

En esta prueba de fail over se mantiene el valor de la cookie JSESSIONID = _id (rojo), pero como hemos actualizado un atributo de la session ha cambiado el campo "lastmodified" (Azul).


Conclusion

Creo que el MongoDB tiene un gran futuro como gestor de persistencia de sesion http y como una cache distribuida (sin ser una cache), no me extrañaria ver en el corto plazo soporte de MongoDB en algún appliaction server comercial como WebSphere Application Server o WebLogic.
Esta prueba que he realizado es solo experimental, no la recomiendo para un entorno productivo dado que aun quedan muchas pruebas por realizar y el Session Manager debe ser mejorado para permitir pasar parametros avanzados al conector java de MongoDB.
 

Comentarios

Entradas populares