Repository navigation
balanceador
Home > Colocar no ar > Balanceador e proxy reverso 🚧
Important
Em desenvolvimento (2.0). Ainda não está numa versão lançada e pode mudar.
Vale para a 2.0 · Delphi XE em diante e Lazarus/FPC 3.2 em diante · Nível: intermediário
Em uma frase: um servidor RAL pode repassar os pedidos de um caminho a um grupo de servidores de trás, escolhendo um por vez (pesos, menos conexões, hash), tirando da roda o que caiu e voltando com ele quando responde: um "API gateway" dentro da sua aplicação.
Você vai precisar: o pacote RALModuleProxyPackage (componentes TRALUpstream e
TRALProxyModule, paleta RAL - Modules).
Grupo := TRALUpstream.Create(Self);
Grupo.Servers.AddServer('http://10.0.0.11:8080');
Grupo.Servers.AddServer('http://10.0.0.12:8080', 2); // recebe o dobro
Proxy := TRALProxyModule.Create(Self);
Proxy.Rules.AddRule('/api', Grupo).StripPrefix := True; // /api/clientes -> /clientes
Proxy.Server := Servidor;O servidor da frente continua um servidor RAL: o motor, o HTTPS e todos os plugins
valem antes do repasse (autenticação, limite de pedidos, lista de IPs, log). Rotas
próprias do servidor convivem com o proxy; as regras são lidas em ordem, a primeira que
casa vence (Path, e Host quando preenchido).
Policy |
escolhe |
|---|---|
lpRoundRobin (padrão) |
cada um na sua vez, pelo peso, sem rajada (o algoritmo do NGINX) |
lpLeastConnections |
o que tem menos pedidos em curso para o seu peso |
lpIPHash |
o mesmo endereço de cliente vai sempre ao mesmo servidor |
lpConsistentHash |
a mesma chave (HashBy: caminho, cabeçalho ou cookie HashName) vai ao mesmo servidor; um servidor que sai move só as chaves dele |
lpRandomTwo |
dois ao acaso, fica o menos ocupado |
-
Backupnum servidor: só recebe quando nenhum outro está disponível. -
Down: tirado da roda à mão.MaxConnections: no máximo N pedidos em curso. -
Sticky.Enabled: o proxy responde um cookie (ralupstream) e o cliente que o traz volta ao mesmo servidor enquanto ele estiver no ar.
-
Passivo:
MaxFailsfalhas (sem resposta) tiram o servidor porFailTimeoutms; depois ele ganha outra chance. -
Ativo:
HealthCheck.Enabledfaz um GET emHealthCheck.Pathde cada servidor a cadaIntervalms;Fallsfalhas seguidas o tiram,Risesacertos o trazem de volta. Combina com oTRALHealthPluginnos servidores de trás (Path := '/health/ready'). -
OnServerChangeavisa quando um sai ou volta. - Um pedido que não chegou a nenhum servidor vai ao próximo (
MaxAttempts, padrão 2) só se o método é idempotente (GET, HEAD, PUT, DELETE...) e nada foi enviado ao cliente ainda: um POST nunca é repetido. Sem servidor disponível: 503; nenhum respondeu: 502; tempo esgotado: 504. -
ConnectTimeout(padrão 5 s) é o tempo para conectar a um servidor antes de tentar o próximo;RequestTimeout(60 s), o tempo sem dado na resposta.
- O corpo do pedido vai como o motor recebeu; a resposta volta em pedaços conforme chega (onde o motor do servidor da frente responde em fluxo), com memória constante.
- Não passam os cabeçalhos de salto a salto (
Connectione os que ele nomeia,Keep-Alive,Transfer-Encoding,Upgrade,Proxy-*...). -
AddForwarded(padrão) mandaX-Forwarded-For,-Protoe-Host; nos servidores de trás, oTRALForwardedPluginlê isso. OX-Forwarded-Forque chegou é trocado pelo cliente que o proxy conhece (ClientInfo.IP): de fora, ele é o que o cliente quiser, e os servidores de trás confiam no proxy. Atrás de outro proxy, ligue oTRALForwardedPlugintambém no servidor da frente (o IP fica o real), ouKeepForwardedChainpara acrescentar à cadeia em vez de trocar. -
Viapõe o cabeçalhoVianos dois sentidos. - Um redirecionamento do servidor de trás volta ao cliente como veio (não é seguido), com
o
Locationdo servidor de trás tornado relativo ao proxy. - Os
Set-Cookiepassam inteiros, com os atributos. Os cookies nunca ficam guardados no proxy: cada usuário recebe só os seus.
StatsPath := '/proxy/stats' cria uma rota com, por servidor: disponível, pedidos em
curso, pedidos, erros e latência p50/p95/p99, em JSON, ou no formato do Prometheus com
?format=prometheus (ral_upstream_up, ral_upstream_requests_total...). Proteja essa
rota (autenticação ou lista de IPs).
O custo é o do motor da frente mais uma chamada de TRALClient por pedido (conexão
mantida com cada servidor de trás). Medido nesta máquina de desenvolvimento, servidor
mORMot2 na frente e três atrás, /ping: cerca de 60% do que o NGINX faz na mesma
bancada. Bom para um gateway dentro da aplicação; para só balancear muito tráfego, use um
balanceador dedicado na frente.
| Sintoma | Causa | Solução |
|---|---|---|
| 404 num caminho que devia ir para trás | nenhuma regra casou (o Path conta segmentos inteiros: /api não pega /apis) |
confira Path, Host e o Domain do módulo |
| 503 | nenhum servidor disponível (todos Down, fora pela saúde ou cheios) |
veja a estatística |
| 502 depois de alguns segundos | o servidor de trás não aceita conexão | confira o endereço; ConnectTimeout menor faz o próximo ser tentado antes |
| o servidor de trás vê o IP do proxy | ele não lê X-Forwarded-For
|
ligue o TRALForwardedPlugin nele |
| um usuário recebe o cookie de outro | (não acontece com o TRALProxyModule) |
um proxy feito à mão com TRALClient precisa de KeepCookies := False
|
Começar
Servidor
- Rotas e parâmetros
- Rotas avançadas: tipos, grupos, versões 🚧
- Ler o pedido e responder
- Resposta em fluxo 🚧
- Plugins 🚧
- Autenticação
- Banco de dados (DBWare)
- Servir site e arquivos
- Swagger e Postman
- Servidor SOAP 🚧
- HTTPS
- Criptografia ponto a ponto
- Segurança para produção
- Colocar no ar
- Desempenho
MQTT 🚧
- O que é e quando usar 🚧
- Cliente MQTT 🚧
- Broker MQTT 🚧
- MQTT-SN 🚧
- Ponte REST 🚧
- Segurança 🚧
- Rede ruim 🚧
Cliente
Motores
Avançado
Ajuda
- Problemas comuns
- Atualizar o Indy
- Várias versões do Delphi
- Vídeos e guias
- Módulos de terceiros
- Licenças
- Contribuir
- Roadmap e changelog
🚧 = em desenvolvimento, pode mudar