Repository navigation
ralproxy
Home > Colocar no ar > RALProxy 🚧
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 programa pronto (exemplo dos Samples, Delphi e Lazarus) que lê um
arquivo de configuração com a sintaxe do NGINX, abre as portas com o
TRALBalancer, grava o log de acesso e recarrega a configuração
sem derrubar as conexões abertas - como console, serviço do Windows ou daemon do Linux.
Você vai precisar: os Samples da 2.0 (Delphi/Console/RALProxy ou
Lazarus/Console/RALProxy), os pacotes PascalRAL, RALNetPackage e
RALModuleProxyPackage, e para HTTPS a OpenSSL ao lado do programa
(dependências).
ralproxy -t -c ralproxy.conf confere e sai (como nginx -t)
ralproxy -c ralproxy.conf roda; Ctrl+C ou SIGTERM termina
Sem -c, lê o ralproxy.conf da pasta do programa. Recarregar: kill -HUP <pid> no
Linux (systemctl reload ralproxy), ou salvar o arquivo no Windows (olhado a cada 2 s).
O serviço do Windows (RALProxyService, só Delphi) e a unidade do systemd
(ralproxy.service) estão no exemplo, com os comandos de instalação.
worker_threads auto;
error_log logs/erro.log;
pid ralproxy.pid;
http {
access_log logs/acesso.log combined;
proxy_read_timeout 60s;
upstream api {
least_conn;
server 127.0.0.1:8101 weight=2;
server 127.0.0.1:8102 max_fails=2 fail_timeout=10s;
server 127.0.0.1:8103 backup;
health_check uri=/health interval=5s fails=3 passes=2;
}
server {
listen 443 ssl;
server_name api.exemplo.com;
ssl_certificate certs/api.pem;
ssl_certificate_key certs/api.key;
location /v1/ { proxy_pass http://api/; } # /v1/x vai como /x
}
server {
listen 80;
location = /status { stub_status; }
location / { proxy_pass http://api; }
}
}
stream {
upstream banco { server 10.0.0.20:5432; }
server { listen 5432; proxy_pass banco; }
}- É um subconjunto da sintaxe do NGINX, lido por um analisador do próprio RAL
(
TRALProxyConfig). Uma diretiva que ele não conhece é erro, nunca ignorada, e o erro diz o arquivo, a linha e a coluna:ralproxy.conf:12:5: unknown directive "servr" in http. -
include arquivo;einclude pasta/*.conf;(em ordem de nome) entram onde estão; caminho relativo é relativo ao arquivo que inclui. - Comentários com
#; valores com espaço entre aspas. - Tempos:
500ms,30s,5m,1h,1d(número sozinho é segundos). Tamanhos:16k,1m. - Os
serverde um mesmolistendividem a porta: os comserver_nameprimeiro, e dentro de cada nome olocationde prefixo mais longo primeiro (como o NGINX); depois o server sem nome ou, sem ele, o primeiro da porta (o servidor padrão do NGINX).
| diretiva | o quê |
|---|---|
worker_threads N; (ou worker_processes) |
threads de cada porta; auto = uma por processador |
error_log arquivo; |
onde vão os erros (sem ele: a saída de erro) |
pid arquivo; |
grava o número do processo (para o kill -HUP) |
events { worker_connections N; } |
aceito e ignorado |
| diretiva | o quê |
|---|---|
access_log arquivo [combined|json]; / access_log off;
|
log de acesso |
keepalive_timeout 75s; |
IdleTimeout |
client_header_timeout 30s; |
HeaderTimeout |
proxy_read_timeout 60s; |
ServerTimeout (servidor mudo: 504) |
proxy_connect_timeout 5s; |
ConnectTimeout de todos os upstreams |
proxy_buffer_size 16k; |
BufferSize |
large_client_header_buffers 4 16k; |
MaxHeaderSize (o último valor) |
sendfile, tcp_nodelay
|
aceitos (o RAL sempre tem) |
keepalive_timeout, client_header_timeout, proxy_read_timeout, proxy_buffer_size e
large_client_header_buffers valem também dentro de um server, só para a porta dele.
| diretiva | o quê |
|---|---|
server host:porta [weight=N] [max_fails=N] [fail_timeout=10s] [max_conns=N] [backup] [down]; |
um servidor; https://host:porta chama com TLS |
least_conn; / ip_hash; / random two;
|
a política |
hash $request_uri consistent; |
hash consistente pelo caminho; $http_<cabeçalho>, $cookie_<nome>, $remote_addr também |
sticky cookie nome; |
sessão grudada pelo cookie |
health_check uri=/health interval=5s fails=3 passes=2 timeout=2s status=200; |
verificação ativa |
keepalive N; |
aceito (as conexões são sempre mantidas) |
| diretiva | o quê |
|---|---|
listen 80; / listen 10.0.0.1:443 ssl;
|
a porta (e o endereço); ssl termina TLS aqui |
server_name a.exemplo.com *.b.exemplo.com; |
os nomes (_ é nenhum) |
ssl_certificate / ssl_certificate_key
|
o certificado deste server (escolhido pelo SNI) |
ssl_protocols TLSv1.2 TLSv1.3; |
a versão mínima |
location /prefixo/ { ... } / location = /caminho { ... }
|
prefixo (sem expressões regulares) |
| diretiva | o quê |
|---|---|
proxy_pass http://upstream; |
repassa como veio |
proxy_pass http://upstream/; |
tira o prefixo do location (/v1/x vai como /x) |
proxy_pass http://10.0.0.5:8080; |
um servidor só, sem bloco upstream
|
proxy_set_header Host $host; |
passa o Host do cliente (é a única forma aceita) |
stub_status; |
a estatística do balanceador (JSON; ?format=prometheus) |
proxy_http_version 1.1; |
aceito |
| diretiva | o quê |
|---|---|
listen 5432; |
a porta (sem ssl: TLS passa sem abrir) |
server_name a.exemplo.com; |
escolhe pelo SNI do ClientHello (vários server na mesma porta) |
proxy_pass upstream; / proxy_pass host:porta;
|
para onde vão os bytes |
proxy_timeout 10m; |
TunnelTimeout |
proxy_connect_timeout 5s; |
ConnectTimeout |
ssl_preread on; |
aceito (o RAL lê o ClientHello sempre que há server_name) |
As portas que ficam continuam abertas, e as conexões que já existem seguem: o próximo
pedido delas usa as rotas novas. Portas novas abrem antes de qualquer coisa mudar; se uma
não abre (ocupada), a recarga é recusada e a configuração anterior continua rodando, com o
motivo no error_log. Uma porta que troca de http para stream, ou liga e desliga o
ssl, fecha e abre de novo.
O que o RALProxy faz está em duas classes da biblioteca (RALProxyConfig):
Config := TRALProxyConfig.Create;
Config.LoadFromFile('ralproxy.conf'); // ERALProxyConfigError com Line e Column
Host := TRALProxyHost.Create;
Host.OnAccess := MeuLog;
Host.Start(Config); // o Host fica com a configuração
...
Nova := TRALProxyConfig.Create;
Nova.LoadFromFile('ralproxy.conf');
Host.Reload(Nova);| Sintoma | Causa | Solução |
|---|---|---|
unknown directive numa diretiva do NGINX |
ela não está no subconjunto | veja as tabelas acima; o RAL não ignora o que não entende |
port N listens with ssl but this server has no ssl_certificate |
listen ... ssl sem certificado no mesmo server |
ponha ssl_certificate e ssl_certificate_key
|
port N is taken twice |
dois stream sem nome na mesma porta, ou http e stream
|
use server_name ou outra porta |
| a recarga não pega | erro no arquivo (veja o error_log) ou, no Windows, o arquivo não foi salvo de novo |
ralproxy -t mostra o erro |
| a porta 80 não abre no Linux | porta abaixo de 1024 sem ser root |
AmbientCapabilities=CAP_NET_BIND_SERVICE (já no ralproxy.service) |
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