Giter VIP home page Giter VIP logo

iasc-load-balancer's Introduction

iasc-load-balancer

TP Cuatrimestral de la materia Implementación de Arquitecturas Concurrentes

Miembros

  • Tomás Milar
  • Juan Pablo de Blass
  • Marcos Paulucci
  • Claudio Yuri
  • Hernán Micelotta

Consigna

Link

Sobre la solución

Decidimos usar nodejs por un tema de familiaridad con el código.

La solución cuenta con un proceso master que levanta tantos procesos workers como CPUs haya disponibles en la computadora donde se corra. Cada uno de estos workers mantiene una lista de servidores disponibles a los cuáles dirigir los requests entrantes.

Como usarlo

Load Balancer

Se corre con el comando

$ nodejs index.js # versión mono proceso [obsoleto]
$ nodejs cluster.js # versión multi proceso

Mock Servers

Se corre con el comando

$ nodejs mock_server.js --port NUMERODEPUERTO --delay ENMILISEGUNDOS --name NOMBREDELSERVER

Supervisor

Opcionalmente se puede usar un heartbeat para monitorear los mock servers, permitiendo que si se caen uno o más servers se marquen como offline para evitar request a servers caídos. Cuando el servidor se normaliza se vuelve a poner online para volver a recibir tráfico.

Para registrar el heartbeat, con el load balancer levantado abrir un navegador e ingresar:

http://localhost:3000/register

Requisitos

Tener redis corriendo en el servidor donde se despliegue el load balancer

Cómo lo levanto

Revisás en archivo config.json

Ahí vás a ver algo parecido a esto:

{
    "listenPort": 3000,
    "serverTimeout": 10, 
    "serverExclusionTime": 10, //tiempo en segundos que se va a exlcuir a un servidor de la lista
                               //luego de ese tiempo, se lo volverá a considerar para enviarle requests
    "maxRetryCount": 3, //cantidad de retries máximo por request
    "debug": true, //define si muestra o no informaición en la consola. para mayor rendimiento se aconseja setear el valor en false
    "cacheTimeout": 10, //duración de la información en caché
    "serverList": [ //esta es la lista de servidores
        "http://localhost:3100",
        "http://localhost:3200",
        "http://localhost:3300",
        "http://localhost:3400",
        "http://localhost:3500"
    ],
    "heartbeat":{
      "executionInterval":10
    },
    "requests":[{
                  "url": "/asd",
                  "servers": ["http://localhost:3200",
                              "http://localhost:3300"]
                },
                {
                  "url": "/hello",
                  "servers": ["http://localhost:3100"]
                },
                {
                  "url": "/heavytask",
                  "servers": ["http://localhost:3500"]
                }
    ]
}

observaciones: solo los patrones marcados en requests se atienden de manera especial, el resto cae en round robin

Luego, abrís varias consolas y vas levantando los mock server de la siguiente manera:

# consola 1
$ nodejs mock_server.js -p 3100
# consola 2
$ nodejs mock_server.js -p 3200
# consola 3
$ nodejs mock_server.js -p 3300
# consola 4
$ nodejs mock_server.js -p 3400
# consola 5
$ nodejs mock_server.js -p 3500

Finalmente, abrimos una consola más y levanamos el load balancer

$ nodejs cluster.js

Ahora podemos abrir un navegador e intentar ingresar a la url donde está nuestro load balancer: http://localhost:3000.

Pruebas con apache bench

Ejemplo de prueba

# usamos '-l' porque el contenido es dinámico y si no lo usamos ab interpreta el reqeust como fallido
$ ab -n 1000 -c 100 -l http://localhost:3000/

iasc-load-balancer's People

Contributors

claudio-yuri avatar hernanutn avatar

Watchers

 avatar  avatar  avatar  avatar

iasc-load-balancer's Issues

Lectura de la configuración a partir de un archivo de config

Podemos definirlo en un JSON (fácil de parsear).

Debe contener:

  1. la lista de servidores disponibles
  2. El tiempo de tolerancia para cada request
  3. Cantidad de minutos en los que se van a marcar como no disponibles los servidores que no responden.

Crear servidor mock

Deberíamos crear un servidor mock que se pueda comportar de diferentes maneras para poder simular diferentes escenarios.

Por ejemplo:

  • podría levantar por archivo de configuración o por parámetro un valor que determine su tiempo de respuesta.
  • Debe responder con algún texto que lo diferencie del resto
  • Debe poder entender los verbos HTTP que necesitamos: GET, POST, PUT

Implementar cluster

Para aprovechar todos los cores deberíamos usar cluster.

Esto nos permite levantar X cantidad de procesos y hacer que cada uno de estos atienda los requests.

Según hablamos con el ayudante la arquitectura usando cluster debería tener en cuenta las siguientes cosas:

  • Contar con N procesos, siendo N la cantidad de núcleos que disponga la PC donde corramos el load balancer (esto se puede sacar con una sentencia de node).
  • 1 de esos N procesos se debería encargar de mantener la lista de servidores (proceso master).
  • Los otros N- procesos :
    • Son los que terminan haciendo los requests a los servidores de destino.
    • Al momento de recibir un request debería poder comunicarse con el proceso master para pedirle un servidor de la lista (cluster ofrece ipc bastante amigable).
    • Si el request al servidor destino falla, deberíamos tener un mecanismo de reintento (que implica volver a pedirle otro servidor al master X veces -definido en el config-).

Excluir los servidores de la lista de disponibles si dan timeout en un request

Si al atender un pedido, el load balancer no puede comunicarse con un servidor, deberá marcarlo temporalmente (durante una cierta cantidad de minutos, también configurable a través del archivo de configuración) como no disponible, y pasar a buscar otro servidor disponible. Lo mismo sucederá si una vez establecida la comunicación el mismo cierra la conexión antes de tiempo o deja de responder (timeout).
Como excepción a estas reglas, si el pedido HTTP utiliza los métodos POST, PUT o DELETE, no se reintentará el pedido.

[OPCIONAL] Implementar heartbeat

Opcional: el load balancer debe ser capaz de detectar proactivamente (es decir, antes de que ocurra un fallo durante una comunicación con el cliente) qué servidores no están disponibles, y también detectar qué servidores no disponibles han vuelto a la normalidad antes de que sea nuevamente necesario redirigirles tráfico.

Realizar benchmark

Una vez construido y desplegado el load balancer, se deberá hacer un benchmark contra un load balancer real, como por ejemplo nginx, utilizando configuraciones similares, bajo al menos tres escenarios diferentes, a elección del equipo. Los resultados del benchmark deberán formar parte de la documentación a entregar.

[OPCIONAL] Implementar caching de requests

Opcional: el archivo de configuración permitirá configurar el caching de pedidos HTTP. En concreto, se podrá indicar en éste que los pedidos GET sean cacheados en el load balancer durante un tiempo configurable, evitando durante ese tiempo tener que acceder a los servidores. La excepción serán los pedidos que contengan el header Cache-Control: no-cache o Expires: 0, que nunca serán cacheados.

SE PUEDE USAR REDIS

[OPCIONAL] el archivo de configuración podrá establecer mapeos más complejos

Opcional: el archivo podrá establecer mapeos más complejos, que permitan dirigir a distintos servidores el tráfico en base a la ruta de cada pedido HTTP. Por ejemplo:

  • Si el pedido apunta a /, redirigir a los servidores a.com, b.com o c.com
  • Si el pedido apunta a /foo, redirigir a d.com o e.com
  • En otro caso, redirigir a a.com, e.com o f.com

Redirigir requests entrante a algún servidor de la lista

Cada vez que un pedido HTTP sea recibido, se deberá elegir en base a la configuración previamente cargada y al pedido cuál es el servidor de destino, y redirigir el tráfico a éste. Esto significa que el load balancer deberá mantener abierta la conexión con el cliente mientras el servidor procesa el pedido, y una vez finalizado, deberá redirigir la respuesta del servidor al cliente.

Nuevamente, tener en cuenta que el proceso debe ser transparente para el cliente, quien no debe jamás comunicarse directamente con el servidor.

  • Implementar el método que reciba el request para cada uno de los verbos HTTP que nos interesan (GET, POST y PUT)
  • Implementar algún algoritmo de selección de servidores disponibles
  • Hacer el request al servidor y contestarle al cliente lo que el servidor nos devuelva
  • Cambiar el request al server remoto para que se haga en formato de promise

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.