Sistemas distribuidos modernos
Tras hablar hoy con un compañero y amigo sobre cómo montar un sistema distribuido, me he dado cuenta de que siempre que hablo de sistemas distribuidos pienso en cosas como CORBA, ZeroC ICE o ZeroMQ. Quizá será porque es lo que me enseñaron en la universidad.
Cuando me pongo a diseñar una aplicación distribuida, comienzo pensando en sistemas de este estilo. Pero cuanto más pienso en la aplicación, menos me encajan, porque todos ellos me hacen la aplicación más compleja.
Me gustaría compartir con vosotros mi hilo de pensamiento habitual.
Diseñando una aplicación distribuida
Vamos a diseñar algo. Por ejemplo, un sistema de integración continua.
Éste tendrá, básicamente:
- Un número indeterminado de agentes que realizan el trabajo.
- Un planificador de trabajos a ejecutar, en función de eventos (tiempo, cambios en un repo, etc).
- Una cola de trabajos a ejecutar.
Hmmmm…. Una cola de trabajos a ejecutar. Eso suena a cola de mensajes, así que vamos a ver qué ocurre si usamos una cola de mensajes para implementarla.
Colas de mensajes
Tendríamos:
- Los agentes se conectan a la cola de mensajes
- Cuando hay un trabajo, un agente disponible puede procesar el trabajo, balanceando la carga automáticamente.
¡Es estupendo! Bueno…. No.
- ¿Cómo se cancela un trabajo?
- ¿Cómo devuelve el resultado el trabajo? ¿Y el streaming de la salida estándar?
- ¿Cómo puedo saber qué trabajos están esperando en la cola?
- ¿Cómo puedo reordenar la cola?
Vaya… Creo que tendré que implementar yo esa cola de mensajes. Lo que implica buscar otro sistema para poder comunicar los servicios.
Sockets
Siempre está la opción de usar sockets a mano, pero eso es muy propenso a errores y hay que gestionar hilos. Casi mejor buscar alguna librería que encapsule eso.
Está ZeroMQ, que es una capa fina sobre los sockets, pero también tiene problemas:
- Si tengo varias colas de trabajo (para tener HA ), y se me cae la conexión actual, ¿cómo localizo una nueva a la que conectarme?
- ¿Cómo puedo pasar por un Firewall? Quizá usando un túnel…
- ¿Tengo que implementarme yo la seguridad a mano?
Lo que me lleva a buscar algo de más alto nivel…
Brokers
Quizá teniendo un broker con servicio de Location, como CORBA o ZeroC ICE, tendría todo el problema resuelto.
Eso resuelve la seguridad y la location, pero… sigo con problemas: el despliegue se complica, tengo que atarme a un framework y sigo sin poder pasar por un Firewall.
Si pudiera buscar algo más simple… Lo más simple de lo más simple…
REST
Y siempre vuelvo la mirada a REST. REST es simple, multiplataforma, escalable, multilenguaje, etc. Utiliza puertos estándar que nadie suele cerrar.
REST se puede implementar sobre casi cualquier protocolo orientado a conexión, aunque es típico de HTTP.
Este tipo de sistemas permiten resolver la mayor parte de problemas de forma simple:
- Sistema de location: basta con devolver un error 403 con la nueva URL a la que conectar.
- Autodescubrimiento de servicios: cuando una respuesta devuelve las posibles operaciones como parte de la response.
- Seguridad: HTTPS
- Autenticación: mediante protocolos ampliamente usados como OAUTH
Conclusión
Hay muchas formas de implementar sistemas distribuídos, pero parece estar de moda usar servicios REST. Bueno… más exactamente micro-servicios REST.
Como ejemplo pondré toda la gama de productos de Elastic, ya que todos se comunican mediante ElasticSearch, del que escribiré en el próximo post.