Esta es una pregunta muy abierta, pero intentaré ilustrar por qué Elixir / Erlang puede ser la mejor plataforma que existe para desarrollar sistemas distribuidos (independientemente de si está trabajando con microservicios).
Primero, comencemos con algunos antecedentes. Erlang VM y su biblioteca estándar fueron diseñadas por adelantado para construir sistemas distribuidos y esto realmente se nota. Hasta donde yo sé, es el único tiempo de ejecución y VM que se usa ampliamente en la producción y está diseñado por adelantado para este caso de uso.
Aplicaciones
Por ejemplo, ya ha insinuado "aplicaciones". En Erlang / Elixir, el código está empaquetado dentro de aplicaciones que:
- se inician y detienen como unidad. Iniciar y detener su sistema es una cuestión de iniciar todas las aplicaciones en él
- proporcionar una estructura de directorio unificada y una API de configuración (¡que no es XML!). Si ya ha trabajado y configurado una aplicación OTP, sabe cómo trabajar con cualquier otra
- contiene el árbol de supervisión de su aplicación, con todos los procesos (por proceso me refiero a "procesos de VM" que son subprocesos de cálculo livianos) y su estado
El impacto de este diseño es enorme. Significa que los desarrolladores de Elixir, cuando escriben aplicaciones, tienen un enfoque más explícito para:
- cómo se inicia y detiene su código
- ¿Cuáles son los procesos que forman parte de una aplicación y, por tanto, cuál es el estado de la aplicación?
- cómo esos procesos reaccionarán y se verán afectados en caso de fallas o cuando algo sale mal
No solo eso, las herramientas en torno a esta abstracción son excelentes. Si tiene instalado Elixir, abrir "iex" y escriba: :observer.start()
. Además de mostrar información y gráficos sobre su sistema en vivo, puede eliminar procesos aleatorios, ver su uso de memoria, estado y más. Aquí hay un ejemplo de cómo ejecutar esto en una aplicación Phoenix:
La diferencia aquí es que las aplicaciones y los procesos le brindan una abstracción para razonar sobre su código en producción . Muchos lenguajes proporcionan paquetes, objetos y módulos principalmente para la organización del código sin reflejarse en el sistema de ejecución. Si tiene un atributo de clase o un objeto singleton: ¿cómo puede razonar sobre las entidades que pueden manipularlo? Si tiene una pérdida de memoria o un cuello de botella, ¿cómo puede encontrar la entidad responsable de ello?
Si le pregunta a cualquiera que ejecute un sistema distribuido, ese es el tipo de información que desea, y con Erlang / Elixir lo tiene como componente básico.
Comunicación
Todo esto es realmente solo el comienzo. Al construir un sistema distribuido, debe elegir un protocolo de comunicación y el serializador de datos. Mucha gente elige HTTP y JSON que, cuando lo piensa, es una combinación muy detallada y costosa para realizar lo que realmente son llamadas RPC.
Con Erlang / Elixir, ya tiene un protocolo de comunicación y un mecanismo de serialización listos para usar. Si desea que dos máquinas se comuniquen entre sí, solo necesita darles nombres, asegurarse de que tengan el mismo secreto y listo.
Jamie habló sobre esto en Erlang Factory 2015 y cómo pudieron aprovechar esto para construir una plataforma de juego: https://www.youtube.com/watch?v=_i6n-eWiVn4
Si desea utilizar HTTP y JSON, también está bien y las bibliotecas como Plug y los marcos como Phoenix le garantizarán que sea productivo aquí también.
Microservicios
Hasta ahora no he hablado de microservicios. Eso es porque, hasta este punto, realmente no importan. Ya está diseñando su sistema y nodos en torno a procesos muy pequeños que están aislados. ¡Llámalos nanoservicios si quieres!
No solo eso, también están empaquetados en aplicaciones, que los agrupan como entidades que se pueden iniciar y detener como una unidad. Si tiene aplicaciones A, B y C, y luego desea implementarlas como [A, B] + [C] o [A] + [B] + [C], tendrá muy pocos problemas para hacerlo debido a su diseño inherente. O, mejor aún, si desea evitar agregar la complejidad de las implementaciones de microservicios en su sistema por adelantado, puede implementarlas por completo en el mismo nodo.
Y, al final del día, si está ejecutando todo esto utilizando el Protocolo distribuido de Erlang, puede ejecutarlos en diferentes nodos y podrán llegar a otros siempre que se refiera a ellos por en {:node@network, :name}
lugar de :name
.
Podría ir más lejos, pero espero haberte convencido en este momento. :)