Archivo por meses: abril 2014

Servicios de almacenamiento en Microsoft Azure: Colas

Muchos son los servicios de Microsoft Azure tanto para PAAS, SAAS cómo para IAAS. En este post me voy a centrar en una pequeña parte de PAAS cómo son los servicios de almacenamiento en esta paltaforma.

Este servicio proporciona varias soluciones,

Blobs: Almacenamiento de grandes bloques de texto o ficheros de gran tamaño; texto, vídeos, audio e imágenes accesible fácilmente mediante una API REST.

Tablas: Almacenamiento NOSQL para datos preparado para que se puede escalar automáticamente y dar cabida a una enorme cantidad de datos. Los datos son accesibles mediante cualquier lenguaje de programación .net, java, node.js, python, rest…

Colas: No son mas que un sistema de almacenamiento FIFO (First In First Out) donde podemos guardar mensajes que debe ser procesadas en segundo plano o en un momento concreto y diferente del proceso principal.

Cabe destacar que todos los servicios de almacenamiento de Azure nos permiten tener una redundancia de datos local (varias réplicas en la misma región), redundancia de datos geográfica (varias réplicas en diferentes regiones)  para dar más eficiencia en la trasferencia de datos y su durabilidad.

Cómo toda interacción con Azure, es sencillo su uso aunque debemos tener en cuenta varios aspectos. Lo primero que haremos será conectar y crear un cliente para conectar con nuestra cola de Azure,

CloudStorageAccount storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString"));
CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();
CloudQueue queue = queueClient.GetQueueReference("nombredelacola");

Estas líneas anteriores nos permiten tener conexión con nuestra cuenta de Storage de Azure, tener un cliente para la conexión con ella y un cliente para manejar la cola. Para manejar la inserción de datos en ella debemos tener en cuenta algunos campos,

Dequeue Count: Número de veces que el mensaje ha sido leído de la cola.
Expiration Time: Momento en el que el mensaje expirará y será eliminado automáticamente por Azure.
Next Visible Time: Momento en el que el mensaje dejará de ser invisible y volverá a poder ser leído al obtener el siguiente mensaje de la cola.
Message: El mensaje con su contenido dentro de la cola.

CloudQueueMessage msg = new CloudQueueMessage("RowKey: 1, RowValue: 55, Action: Send");
queue.AddMessage(msg);

El mensaje es totalmente personalizado, es decir, el Message que hemos creado con “RowKey: 1, RowValue: 55, Action: Send” es porqué el lector de la cola sabrá interpretar este mensaje y podría ser totalmente otro formato y de mayor tamaño, por ejemplo, “PK:1#Value:55#Accion:S” u cualquier otro. Además el Message puede ser texto o byte[] por lo que podréis decidir que almacenar en él.

Si no se especifica parámetros en el Expritation Time ni en el Next Visible Time estos son el de 60 minutos para el primero y un DateTime.Now para el segundo.

Para obtener los mensajes de la cola únicamente es necesario hacer un GetMessage,

CloudQueueMessage msg = queue.GetMessage();

El GetMessage permite pasar cómo parámetro un TimeStamp que es el tiempo que va aparecer oculto el mensaje en la cola y nadie podrá leerlo, si no se especifica ningún tiempo el mensaje leído permanece 3 segundos oculto de la cola.

Tenemos que gestionar un aspecto muy importante, la visibilidad del mensaje.  La lectura de un mensaje no destruye el mensaje y puede ser leído desde diferentes sitios u otra vez por el mismo desencolado y puede ser un problema. Esto es debido a que un mensaje al ser leído es ocultado pero no eliminado por si sucede algún error en la lectura de ese mensaje, en caso de error, el mensaje volvería aparecer en la cola para ser procesado otra vez.

Por eso, es muy importante gestionar el tiempo de ejecución de las tareas y tener en cuenta el tiempo en que es invisible una tarea (un mensaje). Un mensaje debe ser eliminado de la cola únicamente cuando esta se ha procesado correctamente o cuando su Dequeue Count sea de un valor especificado, es decir, lo hemos leído demasiadas veces.

Si procesamos un mensaje y este no se ha podido procesar o no es su momento; imaginar una cola que debe ejecutar el mensaje en un momento determinado y al procesar su verificación determina que precisa un minuto más. Lo que debemos hacer es actualizar el mensaje,

queue.UpdateMessage(msg, TimeSpan.FromSeconds(60), MessageUpdateFields.Visibility);

Esta actualización lo que hace es realizar una actualización en el mensaje y le indicamos que queremos que durante un minuto más ese mensaje no sea visible y por lo tanto, hasta pasado ese tiempo no se podrá obtener y su Dequeue Count augmentará en una unidad. Esta también lo hara por cada GetMessage.

Como veis el último parámetro es una enumeración que es Visbility o bien Content dónde indicamos si estamos cambiando el contenido del mensaje o bien la visibilidad. En este caso la visibilidad.

Cuando el mensaje sea procesado y la tarea ejecutada correctamente, debemos eliminar ese mensaje de la cola para que no vuelva a ser procesado,

queue.DeleteMessage(msg);

Bien, con esta explicación, podemos gestionar de forma muy fácil, sencilla y rápida nuestra cola mediante un WebRol con una tarea en segundo plano que gestione la cola en de Microsoft Azure.

Este sistema es altamente recomendable en sistemas con muchas usuarios dónde necesitamos procesar tareas en segundo plano, que tengan una complejidad de procesamiento alta o bien necesitemos que esas sean procesadas y escalables rápidamente y de forma seguro.

Happy enqueue & dequeue! :)