martes, 21 de mayo de 2013


En otra entrada les comentaba sobre una plataforma para soluciones de integración e interoperabilidad que estoy diseñando/desarrollando sobre la base de la suite de WSO2.

Una de las subplataformas que componen la plataforma integral era la de Seguridad, que tiene como base al Identity Server de WSO2. Las otras se vinculan al BAM y al ESB y dedicaré futuras entradas a ellas.

Entre los elementos más importantes de esta plataforma es que brinda soporte a los RNF relacionados con la alta disponibilidad y la escalabilidad de las soluciones, algo sumamente importante desde el punto de vista de arquitectura, como pueden apreciar en esta otra entrada un poco más genérica y abarcadora.

En esta entrada quiero seguir con este tema de las plataformas y mostrarle como pueden ser usadas y desplegadas en diferentes entornos de hardware en función de los RNF que se quieran lograr.

Gracias a la tecnología empleada por WSO2 para el desarrollo de sus componentes y herramientas, OSGI, se pueden emplear varios esquemas de despliegue.

El primero es, luego de empaquetar todos los componentes necesarios en una única solución software, desplegar  la misma en un único servidor como pueden ver en la siguiente imagen.

Fig. 1. Esquema de despliegue en un solo servidor.

Si se desea mantener la idea inicial de tener 3 subplataformas (seguridad, monitoreo e integración) pues se puede emplear el siguiente esquema de despliegue.

Fig. 2. Esquema de despliegue en 3 servidores.

Ahora bien, si se nos han dado RNF relacionados con alta disponibilidad, escalabilidad y rendimiento entonces cada subplataforma debe ser clusterizada siguiente el siguiente esquema.

Fig.3. Esquema de despliegue de un clúster.

Como pueden ver este esquema sirve para el primer esquema de despliegue y también para el segundo. Solo hay que tener en cuenta que cada plataforma debe ser clusterizada usando el esquema mostrado arriba donde existe un nodo management y N nodos workers y un ELB o Elastic Load Balancer que se encarga de balancear la carga. Lo interesante es que un solo nodo ELB o un clúster del ELB se puede utilizar para todas las soluciones que se pongan detrás de él.

Cuando usar cada uno de estos esquema depende de los requerimientos del cliente. Está claro que el primero es para escenarios donde no existe el hardware adecuado para tener varios servidores físicos o virtualizados o donde se desea tener un todo en uno

El segundo potencia más el funcionamiento de cada subplataforma por separado y es cuando tenemos para usar 3 servidores en este tipo de soluciones.

Si el cliente nos pide una solución clusterizada  pues aplicamos el esquema 3 al esquema 1 o 2.

Los que vienen de plataformas privativas como ORACLE o TIBCO pues están acostumbrados a una sola pieza de software que lo tiene todo ya bien integrado, pero más que nada es una cuestión de gusto y de costumbre. Además de que se hace difícil integrar las más de 15 herramientas de WSO2 en una sola :-D

La seguridad en los servicios web.

La seguridad siempre es un tema importante en cualquier desarrollo de software, y en el caso de los servicios web no es la excepción, pero en muchos casos los desarrolladores tienen sus dificultades implementando los diferentes escenarios requeridos dado la complejidad de los estándares y las herramientas a utilizar.

Para empezar la seguridad en los servicios web se divide en 2 grandes partes:

  1. Seguridad a nivel de transporte: en este caso la seguridad está en el canal de comunicación el cual se encriptar usando algún algoritmo previamente acordado entre el emisor y el receptor y se puede identificar por el uso de https en los endpoint de los servicios web. Básicamente encripta el canal de comunicación dejando desprotegidos los mensajes que viajan en su interior. Lo malo que le veo es que los mensajes pueden ser leídos luego de dejar el canal encriptado. Generalmente se utilizan tokens de usuario y contraseña, o UserName Token,  para fines de autenticación.
  2. Seguridad a nivel de mensaje: en este caso la seguridad puede requerir o no que el canal de comunicación esté encriptado, pero como tal la seguridad se aplica al nivel del mensaje.
    Se puede:

Firmar los mensajes a partir del uso de llaves públicas/privadas. Esto garantiza que la información o no sea modificada y en caso de que lo sea se identifique fácilmente. La firma se realiza usando la llave privada y puede ser comprobada por cualquiera que tenga la llave pública correspondiente. También garantiza el no repudio de la información enviada.

Encriptar los mensajes a partir del uso de llaves públicas/privadas. La idea aquí es que aunque se capture el mensaje no se pueda leer su contenido si no se tiene la llave privada correspondiente a la llave pública que se usó para encriptar el mensaje.

Estos escenarios se pueden combinar de múltiples formas y eso es lo que hace la suite de WSO2 y por lo tanto la plataforma de seguridad, como pueden ver en la siguiente imagen donde se muestra un listado de los escenarios de seguridad que se brindan en la actualidad.


El escenario más complicado de implementar a mi entender  es el 15, en el cual se usan los estándares WS-Trust y WS-SecureConversation para establecer una conversación en un escenario seguro entre un cliente que desea acceder a un recurso que es Proxiado por el ESB y el ESB debe validar las credenciales contra un servidor de seguridad que emite y valida token STS. Los mensajes intercambiados van firmados y encriptados.



Lo interesante aquí es que mientras los extremos de la conversación no confían entre si todos los mensajes se protegen usando algoritmos asimétricos, pero una vez que se establece la confianza se pasa a una protección usando un algoritmo simétrico. Esto se debe a que el costo computacional de los algoritmos asimétricos es mayor que los algoritmos simétricos.

En esta figura pueden observar los pasos principales que  se siguen en la comunicación entre cada una de las partes.




Para implementar estos escenarios de manera general solo necesitamos la plataforma de integración y la plataforma de seguridad, como pueden ver en la siguiente imagen donde se expone un servicio proxy que implementa internamente un mecanismo de ruteo a 2 servicios, uno asegurado a nivel de  transporte y otro a nivel de mensaje. Se usa el IS en un caso para obtener un STS y en el otro caso para una autorización de grano fino usando XACML.


En otras entradas les iré mostrando ejemplos de cómo exponer servicios que usen estos escenarios y a implementar clientes que consuman estos servicios.

lunes, 20 de mayo de 2013


Entre los patrones de integración de Gregor Hohpe el de adaptador  al canal es uno de los más usados.

Se utiliza cuando deseamos acceder a un sistema legado y se nos pueden presentar 3 vías de acceso:

  • Si tenemos acceso a la BD podemos consultar las tablas de la BD y obtener información del sistema. Para eso podemos usar los servicios de datos, como ya lo explicamos en esta entrada.
  • Si tenemos acceso al código fuente podemos crear servicios de lógica de negocio que encapsulen funcionalidades del sistema y exponerlos vía servicios web. El framework que usemos para realizar esta implementación depende del lenguaje de programación pero en mi experiencia si están usando PHP les sugiero usar WSF-PHP y si están usando JAVA usen Axis2.
  • Si no tienen acceso ni a la BD ni a la lógica de negocio pues  aún pueden usar técnicas de scrapping para navegar por  la interfaz gráfica y obtener información del sistema. Con estas técnicas pueden autenticarse en la aplicación y navegar por los enlaces hasta llegar a donde desean y sacar la información directamente del HTML.

Uso de la plataforma de Seguridad para soluciones de Single Sign On.

Una solución de SSO generalmente sigue los pasos que pueden apreciar en la imagen anterior.

Un usuario intenta autenticarse en una aplicación web, alojada en un servidor de aplicaciones, y es redirigido a un servidor Single Sign On, donde  se comprueba si está autenticado o no, si ya se ha autenticado antes entonces se le concede el acceso, en caso de que no esté autenticado pues se le muestra una página donde pueda introducir sus credenciales, ej: usuario y contraseña, luego de que la autenticación es exitosa es redirigido nuevamente a la aplicación web pero llevando consigo una cookie, un ticket y un id del servicio al que se ha autenticado, esto para evitar en futuras autenticaciones tener que volver a introducir el usuario y la contraseña.

La herramienta Identity Server de WSO2 en sus últimas versiones incluye un servidor de SSO y se está trabajando por parte de WSO2  en crear  un agente para aplicaciones web desarrolladas en JAVA. Yo por mi parte también he implementado un agente para SSO en aplicaciones web JAVA con el objetivo de usar esta funcionalidad en la plataforma de seguridad y que la aplicaciones que desarrolle no tengan que preocuparse por implementar módulos de autenticación.

Anteriormente trabajaba con la herramienta CAS, la preferida por muchos para soluciones SSO, pero dada las funcionalidades añadidas de la plataforma de seguridad me es más útil usarla en este tipo de escenarios. Lo bueno que tiene el CAS es su comunidad mucho más grande que la de WSO2  y que tiene ya agentes creados para diversos lenguajes de programación y aplicaciones, en este último caso tenemos como ejemplo al Liferay, un portal empresarial muy usado.

martes, 14 de mayo de 2013

Patrones de Diseño de Arquitecturas de Software Enterprise. II


En la entrada anterior introducía este tema de patrones para aplicaciones Enterprise, y había dejado colgado un problema que considero bastante serio: el desacople que debe existir entre la lógica de proceso y la lógica de negocio, o entre la lógica de aplicación y la lógica de dominio, como lo quieran ver.
En esta entrada le damos continuidad al problema y proponemos una solución viable.
Elementos que buscamos:
  1. El modelo de dominio debe modelar el dominio general y poseer las reglas inherentes a este dominio. Esto debe permitir que pueda ser reutilizado en diferentes aplicaciones. Donde cada aplicación puede tener sus propias transacciones, operaciones, sobre este dominio de forma particular.
  2. Si la aplicación maneja diferentes formas de presentación: (web, desktop, mobile) la lógica de aplicación estaría en esta capa cliente, lo que no es bueno pues dificulta su mantenimiento.
Estos dos elementos nos llevan a determinar que necesitamos una nueva capa que cree una indirección usando el patrón Fachada. Esta sería la capa de servicios.

Esta capa de servicio expone las funcionalidades, servicios, hacia la capa de presentación lo que permite hacer más “flacas” las implementaciones de la presentación las cuales solo tienen que preocuparse por los servicios expuestos y que pueden consumir. La capa de servicios tiene la responsabilidad de definir las interfaces a exponer, APIs o contratos de servicios, que determinan como puede ser usada y las funcionalidades a exponer.
Esta nueva capa nos permite un desacople enorme, ya que la capa de presentación no tiene que estar “pegada” al resto de la aplicación, puede encontrarse en un lugar remoto y solo preocuparse por invocar a los servicios expuestos en la capa de servicios.
Y es que si se diseña bien se tendrá esta capa de servicios, y cada servicio podrá ser expuesto como un servicio web/restful y ya podrá formar parte del proceso de integración. De lo contrario habrá que acceder directamente a su BD saltándonos reglas de negocio y funcionalidades para poder al menos integrar algo.
Seguimos:
Es importante entender que en la capa del modelo del dominio va lo común a un dominio determinado y que es independiente de una aplicación en particular, por lo que puede ser reutilizado por varias.
Es en la capa de servicios donde irá la lógica de aplicación o de procesos específica para aplicaciones además de que a través de esta capa también es recomendable exponer las funcionalidades comunes de la capa de modelo del dominio.
Hasta este momento casi que hemos resuelto todos los problemas que se nos pueden presentar con esta estructura en capas, pero queda uno aun fundamental, y es que la capa de modelo del dominio aun conoce demasiado de la capa de datos. Lo cual atenta contra el bajo acoplamiento que siempre queremos buscar.
La solución nuevamente es crear una indirección a través de otra capa: la capa de persistencia.
Esta capa nos permite evitar que el modelo de dominio conozca de la estructura de las BD o de la manera en que los datos se guardan, se persisten y donde es que se guardan. Esto es así porque el problema tecnológico de los datos no tiene nada que ver con la lógica del dominio. Por eso esta capa de persistencia asume toda esta responsabilidad para desacoplarla.


Al final nos quedará lo siguiente:



Como ven todo queda bien claro ahora y las ventajas saltan a la vista:

La separación de responsabilidades es enorme, lo cual siempre es bueno.
  • El desacoplamiento se mantiene en cada momento.
  • La reutilización se potencia por todos lados.
  • Podemos usar diferentes formas de presentación.
  • Estamos independizados de la forma y del mecanismo de persistencia.
  • Podemos distribuir las funcionalidades buscando alto rendimiento y escalabilidad de las soluciones. Este tipo de distribución se puede hacer en capas físicas (tiers) que a veces se confunden con las capas lógicas (layers).
  • Las reglas y la lógica del dominio se separan de las reglas y lógicas específicas de las aplicaciones.
 

 En estos casos una forma de despliegue típico es la siguiente:

Interesante verdad?

Introducción a la Plataforma de WSO2. IV


Para terminar con la serie que describe las herramientas de la suite de WSO2 vamos a revisar las últimas 4 herramientas.
 

1.       Business Rules Server: en la entrada anterior habíamos hecho mención de servicios de regla de negocio y eso es precisamente lo que hace esta herramienta. Nos permite el desarrollo de servicios web que exponen reglas de negocio. la utilidad consiste en que podemos extraer de los sistemas las reglas de negocio, implementarlas como servicios y exponerlas para cualquier aplicación que las requiera y que tenga permiso para acceder a ellas. Estas reglas de negocio se implementan gracias al uso de Drools como motor de reglas y a la implementación de clases que definen los mensajes de entrada y de salida que cargan los parámetros de entrada que sirven para evaluar la regla y los parámetros de salida que determinan la respuesta a entregar al cliente.

2.       API Manager: esta es una de las herramientas más nuevas de la suite. Permite el desarrollo de APIs así como la gestión de su ciclo de vida, el control de acceso a la misma y la gestión de la calidad del servicio o QoS.

3.       Cloud Gateway: esta herramienta actúa como una pasarela entre los recursos empresariales de una  empresa y aquellos recursos desplegados en una nube permitiendo la comunicación segura y confiable entre ambos extremos.

4.       Complex Event Processor: la gestión de eventos complejos siempre es un tema importante en las empresas, el cómo se responde a un conjunto de eventos que ocurren en tiempo real o casi real es de suma importancia. Eso es lo que nos permite implementar esta herramienta. Su combinación con el BAM es fundamental para la monitorización de una organización y sus activos de tecnología.

Hay una herramienta que no incluí en este listado y creo que es de las más interesantes y que menos se comentan dentro de la comunidad de desarrolladores de WSO2, me estoy refiriendo al AppFactory. Esta herramienta pretende cubrir todo el ciclo de desarrollo gracias a la integración continua, lo cual pueden observar en la imagen debajo. No la he probado ni se si la liberarán bajo la misma licencia y de manera gratis lo que si se es que constituye un paso de avance significativo para su comunidad de desarrollo.


 

Patrones de Diseño de Arquitecturas de Software Enterprise. I



Un patrón se puede definir como el “mecanismo que nos permite enlazar una solución conocida y probada con un problema que se repite sistemáticamente. Y cada vez que se da el problema y se le aplica la solución, el problema se resuelve. Si a este par de problema-solución le agregamos una explicación y un ejemplo de cómo aplicar la solución al problema pues ya tenemos creado un patrón”.
Algunos de los muchos tipos de patrones que nos podemos encontrar:
  • Patrones para la definición y diseño de Casos de Uso,
  • Patrones para el modelado del Negocio,
  • Patrones para flujos de trabajo,
  • Patrones de diseño GRASP,
  • Patrones de diseño de la banda de los cuatro. Orientados a objetos,
  • Patrones de arquitectura,
  • Patrones de integración,
  • Patrones de diseño orientados a servicios.
En esta entrada quiero centrarme en los que tienen que ver más con la arquitectura y los temas de integración: Patrones de arquitectura y de diseño de aplicaciones.
Como aparece en el título de este post no me centraré en cualquier tipo de aplicación, si no en las “Aplicaciones Enterprise”, que se pueden definir como las aplicaciones que usan una arquitectura cliente/servidor con 3 o más capas arquitectónicas.

Entre las características de estas aplicaciones podemos listar las siguientes:
  • Datos masivos (gran volumen) y persistentes,
  • Acceso concurrente, lo que implica gran cantidad de usuarios,
  • Variedad de interfaces de usuario, lo que implica diversidad en la funcionalidad brindada,
  • Integración con otros sistemas, lo que implica que comparten funcionalidad y / o datos,
  • Disonancia conceptual (modelo de datos con distintas visiones), debido a que poseen un modelo de negocio subyacente que abarca distintos aspectos de un área de negocio. Por lo tanto prestan distintas funcionalidades a distintos tipos de usuarios,
  • Lógica de negocio, lo que implica procesamiento de datos.
Ejemplos típicos de estos sistemas son:
  • B2C ( comercio electrónico),
  • sistemas financieros en línea,
  • sistemas ERP ( Enterprise Resource Planning),
  • ECM.
Estos sistemas por su volumen están generalmente instalados físicamente en varios nodos (servidores). Por sus características de crecimiento es importante en su diseño el concepto de escalabilidad y por la necesidad de prestar servicios en forma continua es importante el concepto de robustez. Ambos conceptos condicionan el diseño de la arquitectura de este tipo de sistemas.
Estos tipos de sistemas ejemplificados todos comparten la estructura cliente/servidor y se estructuran en capas, por eso digo que estas son las dos características fundamentales para identificar “sistemas enterprise”.

Las capas más comunes son las siguientes:
  • Capa de Presentación:
    Esta es la capa que está de cara a los usuarios humanos, exponiendo UI. Para esta capa podemos usar patrones de presentación web como los de Martin Flowler. En esta capa se maneja la lógica de aplicación.
  • Capa de Servicios:
    Esta es la capa que está de cara a los usuarios no humanos, otros sistemas, exponiendo APIs o servicios. En ella se resuelven los problemas del acceso a las funcionalidades de las aplicaciones a través de sus modelos de objetos y de la lógica de aplicación, o de proceso como me gusta decir, para diferenciarla de la lógica de negocio. Se pueden emplear los patrones de distribución de Martin Flowler. En esta capa se maneja tanto la lógica de aplicación como la lógica de negocio.
  • Capa de Dominio del Problema:
    En esta capa se modelan los problemas de modelado del dominio y del negocio de la aplicación. Se pueden usar todos los patrones de diseño de la “GoF o Banda de los Cuatro”. Se enfoca fundamentalmente en el modelado del problema y la lógica de negocio.
  • Capa de Persistencia:
    En esta capa se resuelven los problemas propios de la persistencia de los objetos en BD relacionales así como el acceso multiusuario a estos SGBD y las operaciones ACID y CRUD. Los patrones a utilizar aquí son disímiles casi todos los podemos ver en la documentación de Martin Flowler.
En este tipo de aplicaciones Enterprise se acepta casi cualquier tecnología para la capa de presentación, pero para las demás generalmente solo hay dos propuestas que persisten según mi criterio personal: JAVA y .NET.
Dado el tipo de aplicaciones seleccionado, es decir del tipo Enterprise, donde las aplicaciones poseen un dominio complejo, con lógica de negocio compleja y muchas reglas de negocio, las cuales varían con el tiempo, y van modificando a las actuales, y nutriéndose con otras nuevas, la idea central es modelar el dominio utilizando programación orientada a objetos, obteniendo así un modelo del dominio, formado por objetos muy similares a la realidad, que se rigen según las reglas de negocio. Esto no es otra cosa que la Orientación a Objetos.



Para poder acompañar los cambios del negocio, actualizando así el modelo del dominio, se busca la manera de mantener este dominio lo más aislado posible del resto de la aplicación y me parece que esto último resume lo que aún no hemos podido interpretar e implementar:


¿Cómo desacoplar el dominio de negocio de nuestras aplicaciones del resto de los componentes de la aplicación de forma tal que los cambios en el dominio del negocio, dígase nuevas reglas, procesos, funcionalidades, puedan ser actualizadas en la aplicación sin tener que hacer un rediseño y re implementación completa de la misma? Vaya que me salió como un problema científico
La solución a este problema es el patrón “Capas” bien empleado, porque cuando se emplea mal no resuelve nada.

La solución más vista puede ser la siguiente:




Es la que casi siempre aparece en cada trabajo que vemos o proyecto que se desarrolla.
El problema con esta estructura es que mientras que en la capa de presentación se maneja la interacción con los usuarios humanos y en la capa de datos se maneja el acceso y persistencia de los datos, en la capa de modelo del dominio se manejan dos cosas que deberían estar separadas:
  • Lógica y reglas del dominio. Lógica de Negocio.
  • Lógica y reglas de la aplicación. Lógica de Procesos.
NOTA: las cosas en negrita son los nombres que yo les doy cuando hablo con otras personas sobre este tema.
Digo que deben estar separadas porque es la única manera en que una aplicación podrá responder a los cambios del negocio de forma adecuada.

Introducción a la Plataforma de WSO2. III


Continuando con la serie donde se describen las herramientas de WSO2 a través de sus principales características o usos ahora le toca a las siguientes.

 

1.       Stratos: esta herramienta a mi criterio es la primera Plataforma como Servicio para JAVA que el mundo del software libre puede utilizar en sus desarrollos. En concreto permite tener en una sola herramienta al resto de las herramientas y poder crear nubes privadas, híbridas y públicas. Existe un despliegue de esta herramienta que pueden encontrar en http://wso2.com/cloud/stratoslive/ y que les permite apreciar las bondades de esta herramienta y las del resto en particular. Para despliegues privados se combina con el ELB para todo lo que tiene que ver con el Balanceo de Carga.

2.       Data Service Server: esta herramienta tiene básicamente un único propósito y es el desarrollo de servicios de datos con acceso a múltiples fuentes de datos, las tradicionales más comunes y también a ficheros CVS, hojas de cálculo Excel, bases de datos no relacionales como Cassandra, acceso a datos en la web a través de técnicas de Scrapping, recursos RDF y JNDI. Estos servicios pueden ser expuestos como tradicionalmente se hace a través de SOAP pero también se pueden exponer como recursos REST. Algo interesante es que permite combinar datos de diferentes fuentes y combinarlos en una sola  respuesta así como consultas anidadas entre diferentes fuentes de datos.


3.       WSF-PHP: en el mundo de PHP hay vario frameworks usados para implementar y consumir servicios web, pero pocos cumplen con todos los estándares WS-*. Ese no es el caso de WSF-PHP que nos permite implementar fácilmente servicios web y consumirlos además de poder brindar otras características como seguridad e implementar diversas políticas de autenticación y autorización.

4.       Business Process Server: esta es una herramienta que aún le queda mucho camino. Su mayor utilidad es la de permitir el despliegue de procesos de negocio implementados en BPEL. Estos procesos se pueden diseñar en el WSO2 Developer Studio y desplegarse entonces en esta herramienta. Una de las cosas buenas que tiene es que muy fácilmente se pueden contactar las tareas con servicios de la plataforma y tener procesos de negocio que usan servicios de datos, servicios de negocio y servicios de reglas de negocio. Si además le sumamos que la herramienta soporta los estándares BPEL4WS y BPEL4People podemos implementar interfaces de usuario y conectarlas a las tarea hechas por humanos. Con lo que damos un paso de avance hacia la integración entre SOA y BPM.

lunes, 13 de mayo de 2013

Un vistazo a la Arquitectura para sistemas escalables y redundantes.

Como el nombre de este post lo indica, quiero dedicarme un rato a escribir sobre arquitectura de software y a dos de los atributos de calidad más deseados por los arquitectos de medianos y grandes sistemas: escalabilidad horizontal y redundancia. En otro post entonces veremos como la suite de WSO2 enfoca estos temas.
Los usuarios siempre desean que el sistema esté funcionando y que lo haga rápido, algo no siempre fácil de lograr:
Desde el punto de vista de la arquitectura la mejor manera de lograr que un sistema esté siempre online y que funcione adecuadamente es que el mismo sea escalable y además redundante.
A un sistema se le puede incrementar su rendimiento si se añade más hardware para que este pueda correr. En estos casos el sistema se ejecuta en una máquina A y se añade una máquina B, para poder duplicar las prestaciones en general. Si luego se añade una máquina C entonces se triplica su rendimiento. A esto se le llama escalabilidad horizontal. La capacidad de poder añadir nuevo hardware al conjunto sin afectar al sistema que los utiliza.
NOTA: Es bueno aclarar que para que un sistema pueda escalar de esta forma debe haber sido diseñado con esta idea en mente, si no luego se hace un poco complicado lograrlo eficientemente.
Por el lado de las fallas, un sistema no debe verse afectado por la pérdida de uno o más de sus servidores replicados, debe ser capaz de funcionar con al menos 1. Una pérdida de este tipo solo debe afectar el rendimiento. A esto se le llama redundancia.
Entonces de lo que estamos hablando es de tener sistemas, mediados o grandes, que puedan distribuirse entre varios nodos servidores y que se repliquen en estos nodos, de forma tal que la caída de uno o más de ellos no afecte el funcionamiento del sistema.

La pregunta es: ¿Cómo se logra?
La solución:

Balanceo de Carga.
El balanceo de carga no es otra cosa que la técnica de enviar peticiones a recursos, seleccionando el recurso basado en determinado algoritmo (aleatorio, round-robin, aleatorio con pesos, etc). O sea es tener varios lugares con la misma capacidad de realizar una tarea, a los que podamos enviar una petición y seleccionar el lugar adecuado basado en algún criterio.
Esta solución nos permite resolver el problema que aparece cuando tenemos una misma aplicación distribuida por ejemplo en 3 nodos diferentes y nos preguntamos cómo lograr que las peticiones de los usuarios se distribuyan entre los 3 nodos y no siempre lleguen a uno solo. U otro problema sería el de que queremos que todas las peticiones lleguen siempre al mismo nodo pero en caso de que este falle, se envíen a los otros nodos.
Como ven al introducir 3 nodos estamos escalando horizontalmente la aplicación, pero igual necesitamos que los 3 nodos sean usados, y además necesitamos que la información en cada nodo sea la misma porque si estamos trabajando en el "nodo 1″ durante un día y este se cae y pasamos al "nodo 2″, que pasa con la información que generó el "nodo 1″. Vaya problema.
Soluciones de BC:
Para el balanceo de carga existen 3 tipos de soluciones reconocidas:
  • Clientes inteligentes: Es cuando un desarrollador se mete a tirar código para manejar como enviar las peticiones a diferentes nodos, subscribirse a nodos, detectar nodos caídos y cosas así. Algo interesante pero que no trabaja bien.
  • Hardware para el balanceo de carga: lo más caro del mundo.
  • Software para el balanceo de carga: lo mejorcito teniendo en cuenta la relación costo/beneficio. Apache Tomcat tiene su software para el balanceo de carga. REDHAT tiene su solución.
O sea que la solución es buscar un buen software que nos permita realizar configuraciones de cada nodo a donde hay que enviar las peticiones y que cuando estas lleguen las distribuya de forma eficiente.
En el caso específico de Apache Tomcat ellos brindan una muy buena solución para potenciar sistemas escalables y redundantes.
Antes mencionaba algunos algoritmos para el balanceo de carga. Vamos a profundizar un poco más:
DNS Round-Robin:Esta técnica no requiere de hardware ni servidores especiales gestionando el balanceo. Simplemente se le dan varias direcciones IP a cada sitio, y se asume que eso va a dar una distribución pareja de las visitas a cada una de las IP asignadas. (y por supuesto, cada una de ellas en un servidor distinto con los mismos contenidos del mismo sitio, replicado o compartido)
Una contra de este sistema es que en caso de que uno de los servidores salga de servicio, todos los usuarios que tengan esa IP van a perder acceso. A veces se busca resolverlo con herramientas como HeartBeat y Fake.
LB Round-Robin:Similar al anterior, pero en lugar de hacer una distribución via DNS, hacemos una distribución al azar a través de un balanceador de carga.
Weighted LB:También utilizamos un balanceador de carga, con la diferencia de que en lugar de hacer una distribución al azar se hace contemplando la capacidad (que un administrador debe definir) relativa entre los servidores web del grupo de balanceo.
Dynamic-Weighted LB:En este caso, no se requiere de un administrador definiendo de forma manual la capacidad de cada integrante del grupo de balanceo, sino que el load balancer puede medir y estimar esto por sus propios medios, a través de monitoreos períodicos de los equipos.
Sticky-Sessions o Sticky-User:Asumamos nuevamente que todos los equipos del grupo tienen las mismas características y capacidades, muchas veces es conveniente (y hasta necesario) que un usuario que haya sido derivado a un servidor web determinado, sea derivado nuevamente al mismo servidor web en caso que vuelva a ingresar. Para ello se usan "Sticky-Session" o "Sesiones pegajosas", donde se "pega" al usuario a un servidor web determinado. En determinados entornos estos es necesario para el funcionamiento correcto de las sesiones, o para maximizar la performance cuando se usan aplicaciones que tienen un alto costo (computacional) de arranque (por ejemplo aplicaciones FastCGI como PHP, Ruby, etc) pero no tan alto de reutilización.
Esto se puede hacer por Cookies o simplemente por IP del usuario que visita. Sin embargo este sistema que se centra en el usuario no tiene muy en cuenta las características de cada servidor de la red, de la misma forma que un LB normal no tienen en consideración las características del usuario.
Dynamic-Weighted Sticky-Session Load Balancing:Un sistema de estas características hace un balanceo de carga considerando el estado y capacidad de cada servidor de la red, distribuyendo los usuarios de un sitio a lo largo de dicha red de forma que cada usuario se mantenga lo más "pegado" posible a un servidor en la medida que eso sea más beneficioso que moverlo a otro, a fin de mantener los tiempos de respuesta parejos para todos.
Como ven, en esto del balanceo de carga lo importante es tener bien claro cuál es el algoritmo que queremos utilizar y claro, el software que lo implemente.
CACHE:
Junto con el balanceo de carga otro de los elementos más importantes y que se combina siempre que se busca desarrollar sistemas escalables y redundantes es el cacheo de la data más usada.
El cacheo permite hacer un uso más eficiente de los recursos que ya se tienen y consiste fundamentalmente en:
  • Almacenar copias de los datos a los que se accede más frecuentemente. Por ejemplo lo que hace MemCached en el tema de las BD y que tanto a ayudado a Facebook con su mysql.
  • Generar índices de búsquedas más comunes o frecuentes, lo que ha ayudado enormemente a google. Porque si yo sé que al día se busca el término "Beyonce" 15 000 veces, tiene sentido que guarde el resultado de esas búsqueda y luego no la tengo que volver a ejecutar, solo muestro lo que ya guardé de la primera búsqueda.
Y así hay muchas otras estrategias de cacheo de datos, siempre buscando optmizar los recursos que ya tenemos. En este tema del cacheo es donde se están colando las BD NoSQL como Cassandra.
Las estrategias de cacheo van desde:
  • Implementar esto a nivel de aplicación, por lo que hay que desarrollar pensando en este asunto.
  • Implementar el cacheo a nivel de BD.
  • Implementar el cacheo en memoria, usando la RAM y el HDD.
  • Implementar el cacheo de páginas estáticas en servidores web, para no tener que generar la información cada vez que se pida.
A veces hay que decidir en donde realizar el cacheo, si en la aplicación o en la BD:
En este caso la información que más se consulta de la BD es almacenada en un sistema aparte y de más rápido acceso para su disposición para ser usada por el sistema.
La otra variante es el cacheo de la BD:
La solución que más se ve es una mezcla de estos dos enfoques.
En el caso del cacheo en memoria se considera como la solución que más mejora el rendimiento de las aplicaciones al poner todos los datos en memoria. MemCached y Redis son dos ejemplos de este tipo de estrategia.
El problema con todo esto es que esa información que es cacheada tiene un tiempo de vida determinado por su veracidad. Esto es que si guardo determinada información por una semana en la cache y durante esta semana la información cambió en el servidor, entonces lo que le muestro al cliente no es real y ya por ahí tengo un problema. La solución más común para este problema es que cada vez que algo cambie en el servidor sea escrito nuevamente en la cache o que se establezca un margen de tiempo luego del cual la cache expire y se genere nuevamente.
Mientras el balanceo de carga permite distribuir el procesamiento entre los diferentes nodos en que se encuentra distribuida la aplicación y la cache ayuda a hacer un uso más eficiente de los recursos existen situaciones en que la latencia, demora en dar la respuesta a un cliente, no depende de la cache ni del balanceo de carga si no de la funcionalidad en si, que se demora en procesarse. Esto puede dar la impresión de un sistema lento y enojar bastante a los usuarios del sistema al este congelárseles mientras se termina determinada acción.

Procesamiento OffLine
Esta es la solución al problema que mencionaba anteriormente. Se puede ejemplificar a través de una situación en que el cliente hace una petición la cual como parte de su procesamiento implica consultar determinado sistema, que bien puede estar offline, u ocupado en otro procesamiento, por lo que el cliente debe esperar hasta que se pueda procesar su petición. Otro ejemplo son sistemas como Facebook, donde cuando publicamos un mensaje el cual es notificado a todos nuestros contactos, el mismo aparece como publicado a nosotros inmediatamente, mientras la publicación y notificación real ocurre fuera de nuestra linea de tiempo en la ejecución de facebook porque es inaceptable tener que esperar por todo el proceso de notificación para dar por terminada esta tarea a ojos de los usuarios.
La mejor forma de lograr el procesamiento offline es crear colas de mensajes. Donde nuestro sistema puede enviar mensajes a una cola para que sean procesados y dicho procesamiento ocurre fuera de nuestro sistema, en otro que se encarga de esa tarea. Este desacoplamiento permite escalar aun más las soluciones al tiempo que promueve el trabajo asíncrono.
Como se ilustra en la imagen parte del procesamiento de la aplicación desplegada en el Web Server se envía a través de una cola a otro sistema, que extrae la información a procesar, realiza el procesamiento y guarda los resultados en una BD, tal vez notificando a la aplicación de que ha terminado su trabajo para que entonces esta consulte la BD en busca de los resultados.
Otro problema a enfrentar cuando buscamos desarrollar sistemas escalables y redundantes es la necesidad de integración que podemos tener, ya que las aplicaciones no existen solas en una empresa. Generalmente tendremos un montón de aplicaciones que comparten funcionalidades e incluso datos y que acceden a sus propias BD pero que a veces deben de acceder a BD de otras aplicaciones. Estas aplicaciones pueden estar desarrolladas en diferentes plataformas de desarrollo y tecnologías lo que complica el tema de integración.
La solución para este tipo de situaciones es crear una capa intermedia que se encargue de manejar todos estos escenarios y libere al web server de este trabajo, con lo cual la escalabilidad del mismo se verá beneficiada.

Capa de Plataforma
Introducir una nueva capa permite crear una indirección en el funcionamiento de nuestra aplicación. Esto es beneficioso pues ayuda en hacerla redundante. Veamos cómo.
Al interponer una plataforma entre nuestro servidor de aplicación y la BD podemos cambiar en tiempo de ejecución de BD ante una caída de la misma, siempre y cuando esto esté soportado, e incluso podemos abstraernos de las complejidades del acceso a la BD pues de estas tareas se encarga la capa de plataforma. Igual si necesitamos acceder a otros sistemas o recursos en la red la capa de plataforma puede realizar este trabajo con lo que el servidor de aplicaciones sufre menos en cuanto a rendimiento y trabajo.
Otra ventaja de este enfoque ya más a un nivel de proceso de desarrollo es que al abstraer los diferentes acceso a sistemas y recursos permite que varios equipos de desarrollo creen sus aplicaciones utilizando esta capa y sus funcionalidades, e incluso que intercambien especialistas al tener todos los mismos conocimientos.

Como ya dije al inicio esta es solo la entrada que da pie a ver como WSO2 enfoca estos temas así que en la siguiente entrada veremos como la empresa wso2 ha implementado componentes para casi todos estos problemas/soluciones.