Load Balancer
Tags: devops, distributedsystems, nginx, node
Published: 2023-05-24 19:06:09

Um **Load Balancer** (balanceador de carga), abreviado como **LB**, é um método de distribuição de tráfego de protocolos de redes entre vários computadores e, geralmente, ele fica na frente da aplicação, ou seja, na frente das máquinas (servidores) que rodam seu back-end, enquanto seu back-end consome sua aplicação e as requisições que ele está recebendo, onde, o Load Balancer fica encarregado de distribuir tudo e manter tudo organizado.

> As grandes empresas como Google, Microsoft, Amazon, Netflix, Apple e entre outras são capazes de receber muitas informações e muitos clientes online em um site ou aplicativo, e isso sem que o servidor acabe caindo e nisso sem ter algum problema de performance, então, obviamente, há um **load balancer** (balanceador de carga) configurado nesse servidor.

Então, todo o hardware tem o seu limite, e muitas vezes o mesmo serviço tem que ser repartido por várias máquinas, sob pena de se tornar congestionado. Estas soluções podem-se especializar em pequenos grupos sobre os quais se faz um balanceamento de carga: utilização do CPU, de armazenamento, ou de rede. Qualquer uma delas introduz o conceito de clustering, ou server farm, já que o balanceamento será, provavelmente, feito para vários servidores.

Em rede de computadores, o balanceamento de carga é uma técnica para distribuir a carga de trabalho uniformemente entre dois ou mais computadores, enlaces de rede, UCPs, discos rígidos ou outros recursos, a fim de otimizar a utilização de recursos, maximizar o desempenho, escalabilidade, minimizar o tempo de resposta e evitar sobrecarga. Utilizando múltiplos componentes com o balanceamento de carga, em vez de um único componente, pode aumentar a confiabilidade através da redundância.

<img src="https://gridscale.io/wp-content/uploads/loadbalancer.svg" height="177" align="right">

> Além disso, se houver problema com alguma máquina, ele será capaz de direcionar o tráfego para outra máquina, sem que o usuário perceba.

Dentro de um Load Balancer, quando ele está rodando na aplicação, existem algoritmos responsáveis por fazer essa distribuição e o melhor disso é que você pode configurar essa distribuição, e não existe somente um algoritmo, mas sim vários algoritmos: com menas conexões, menor tempo de resposta, IP Hash, de duas escolhas aleatórias e entre outros tipos de algoritmos dependendo da maneira que você configurar na sua aplicação e isso é bem customizável. O algoritmo mais comum de todos é o **RR - Round Robin** que é o algoritmo padrão que roda na maioria dos Load Balancers, veja abaixo como esse algoritmo funciona em um balanceador de carga:

### RR - Round Robin
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/76/Round_Robin_Schedule_Example.jpg/700px-Round_Robin_Schedule_Example.jpg" height="177" align="right">

O **Round Robin**, abreviado como **RR**, é um dos algoritmos mais simples de agendamento de processos em um sistema operacional e é padrão para a maioria dos balanceadores de carga pela simplicidade da sua funcionalidade e processamento, que atribui frações de tempo para cada processo em partes iguais e de forma circular, manipulando todos os processos sem prioridades. O escalonamento Round Robin é simples e fácil de implementar.

O algoritmo de escalonamento Round-Robin é um dos mais antigos e simples algoritmos, além de ser totalmente imune a problemas de **starvation** que são tarefas que nunca são executadas em função de ter prioridade inferior as demais.

É usado em projetos de sistemas operacionais multitarefa, e foi projetado especialmente para sistemas time-sharing (tempo compartilhado), pois este algoritmo depende de um temporizador (Timer).

Uma unidade de tempo, denominada quantum, é definida pelo sistema operacional, que determina o período de tempo entre cada sinal de interrupção. Todos os processos são armazenados em uma **fila circular** (circular queue, data structure - estrutura de dados).

Se o quantum é 100 milisegundos e a tarefa leva 250 milisegundos para completar, o agendamento round-robin suspenderá a tarefa após os primeiros 100 milisegundos e dará a outra tarefa da fila, o mesmo tempo. Essa tarefa será executa portanto após 3 agendamentos a saber (100 ms + 100 ms + 50 ms). A interrupção da tarefa é conhecida como preempção.

Tarefa1 = Tempo de execução igual a 250 ms (quantum 100 ms).

1. Primeiro agendamento = executa tarefa durante 100 ms.
2. Segundo agendamento = mais 100 ms de execução da tarefa.
3. Terceiro agendamento = 100 ms, mas a tarefa termina após os primeiros 50 ms.
4. Total de tempo que a CPU levou para a tarefa1 = 250 ms

Um melhoramento desse agendamento é dividir todos os processos em números iguais de frações de tempo e proporcionais ao tamanho da tarefa, assim todos os processos terminam ao mesmo tempo.

<img src="https://user-images.githubusercontent.com/61624336/203871587-807180e8-c77c-43d3-9c1a-eee60983e8bd.png" height="177" align="right">

Nesse exemplo, possuimos os clientes no lado esquerdo (C1, C2, C3, C4), o Load Balancer no meio delas, e as máquinas no lado direito (M1, M2, M3). Então, vamos imaginar que esses clientes estão enviando requisição para um **endpoint** (ponto-final) que vai cair lá no nosso LB, não vamos somente imaginar que 4, mas sim vários clientes enviando requisição para esse endpoint.

E o nosso LB está configurado com o algoritmo de R.R - Round Robin, então esse algoritmo vai sequencialmente distribuir essa carga de tráfego de requisições para cada uma dessas máquinas, ou seja, a primeira que ele vai receber vai distribuir para a máquina 1 (M1), a máquina 2 (M2) e a máquina 3 (M3).

E, assim por diante, para a quantidade de máquinas que ele conseguir enxergar e enviar essa requisição. E, assim que ele acabar, ele vai voltar para a primeira máquina, segunda máquina, terceira máquina e assim por diante. No qual, ele armazena para onde foi enviada a ultima conexão.

### Sticky Round Robin

### Weighted Round Robin

### IP/URL Hash

### Least Time

### Menor número de conexões
O algoritmo de menor número de conexões é especifico para o determinado propósito a qual foi atribuido pelo seu próprio nome, ou seja, ele verifica quantas conexões possuem em cada máquina aberta.  

### Least Connections
Verifica quantas conexões há abertas com cada servidor para decidir para onde enviar a próxima requisição.