Em Balanceamento de carga com NGINX e NGINX Plus, Parte 1, configuramos um proxy HTTP simples para balancear o tráfego entre vários servidores web. Neste artigo, veremos outros recursos, alguns deles disponíveis no NGINX Plus: otimização de desempenho com conexões persistentes, verificações de integridade, persistência de sessão, redirecionamentos e reescrita de conteúdo.
Para obter detalhes sobre os recursos de balanceamento de carga do NGINX e do NGINX Plus, consulte o Guia de Administração do NGINX Plus.
Nota do editor – O NGINX Plus versão 5 e posteriores também podem balancear a carga de aplicações baseadas em TCP. O balanceamento de carga TCP foi significativamente ampliado na versão 6 com a adição de verificações de integridade, reconfiguração dinâmica, terminação SSL e muito mais. No NGINX Plus versão 7 e posteriores, o balanceador de carga TCP oferece todos os mesmos recursos do balanceador de carga HTTP. O suporte ao balanceamento de carga UDP foi introduzido na versão 9.
Você configura o balanceamento de carga TCP e UDP no contexto stream em vez do contexto http. As diretivas e os parâmetros disponíveis apresentam algumas diferenças devido às diferenças inerentes entre HTTP e TCP/UDP. Para obter detalhes, consulte a documentação dos módulos Upstream de HTTP e TCP/UDP.
Uma breve revisão
Para recapitular, esta é a configuração que criamos no artigo anterior:
server { listen 80;
location / {
proxy_pass http://backend;
# Rewrite the 'Host' header to the value in the client request,
# or primary server name
proxy_set_header Host $host;
# Alternatively, put the value in the config:
# proxy_set_header Host www.example.com;
}
}
upstream backend {
zone backend 64k; # Use NGINX Plus' shared memory
least_conn;
server webserver1 weight=1;
server webserver2 weight=4;
}Neste artigo, veremos algumas maneiras simples de configurar o NGINX e o NGINX Plus para aumentar a eficiência do balanceamento de carga.
Conexões HTTP persistentes
Habilitar conexões HTTP persistentes entre o NGINX ou o NGINX Plus e os servidores upstream melhora o desempenho (reduzindo a latência) e diminui a probabilidade de o NGINX ficar sem portas efêmeras.
O protocolo HTTP usa conexões TCP subjacentes para transmitir solicitações HTTP e receber respostas HTTP. As conexões HTTP persistentes permitem reutilizar essas conexões TCP, evitando assim a sobrecarga de criar e encerrar uma conexão para cada solicitação:
O NGINX é um proxy completo e gerencia de forma independente as conexões dos clientes (conexões keepalive de frontend) e as conexões com os servidores (conexões keepalive de upstream):

O NGINX mantém um “cache” de conexões keepalive — um conjunto de conexões keepalive ociosas com os servidores upstream — e, quando precisa encaminhar uma solicitação a um upstream, usa uma conexão keepalive já estabelecida do cache em vez de criar uma nova conexão TCP. Isso reduz a latência das transações entre o NGINX e os servidores upstream, além de diminuir a taxa de uso de portas efêmeras, permitindo que o NGINX absorva e balanceie grandes volumes de tráfego. Em caso de um grande pico de tráfego, o cache pode se esvaziar e, nessa situação, o NGINX estabelece novas conexões HTTP com os servidores upstream.
Com outras ferramentas de balanceamento de carga, essa técnica às vezes é chamada de multiplexação, pool de conexões, reutilização de conexões, ou OneConnect.
Você configura o cache de conexões keepalive incluindo as diretivas proxy_http_version, proxy_set_header e keepalive na configuração:
server { listen 80;
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}
upstream backend {
server webserver1;
server webserver2;
# maintain up to 20 idle connections to the group of upstream servers
keepalive 20;
}Verificações de integridade
Habilitar as verificações de integridade aumenta a confiabilidade do seu serviço com balanceamento de carga, reduz a probabilidade de os usuários finais receberem mensagens de erro e também pode facilitar operações comuns de manutenção.
O recurso de verificação de integridade do NGINX Plus pode ser usado para detectar falhas nos servidores upstream. O NGINX Plus testa cada servidor usando “transações sintéticas” e verifica a resposta de acordo com os parâmetros configurados na diretiva health_check (e, quando você inclui o parâmetro match, no bloco de configuração match associado):
server { listen 80;
location / {
proxy_pass http://backend;
health_check interval=2s fails=1 passes=5 uri=/test.php match=statusok;
# The health checks inherit other proxy settings
proxy_set_header Host www.foo.com;
}
}
match statusok {
# Used for /test.php health check
status 200;
header Content-Type = text/html;
body ~ "Server[0-9]+ is alive";
}A verificação de integridade herda alguns parâmetros do bloco location pai. Isso pode causar problemas se você usar variáveis de tempo de execução na configuração. Por exemplo, a configuração a seguir funciona para tráfego HTTP real porque extrai o valor do cabeçalho Host da solicitação do cliente. Provavelmente, ela não funciona para as transações sintéticas usadas pela verificação de integridade porque o cabeçalho Host não é definido para elas, o que significa que nenhum cabeçalho Host é usado na transação sintética.
location / { proxy_pass http://backend;
# This health check might not work...
health_check interval=2s fails=1 passes=5 uri=/test.php match=statusok;
# Extract the 'Host' header from the request
proxy_set_header Host $host;
}Uma boa solução é criar um bloco fictício location que defina estaticamente todos os parâmetros usados pela transação de verificação de integridade:
location /internal-health-check1 { internal; # Prevent external requests from matching this location block
proxy_pass http://backend;
health_check interval=2s fails=1 passes=5 uri=/test.php match=statusok;
# Explicitly set request parameters; don't use run-time variables
proxy_set_header Host www.example.com;
}Para mais informações, consulte o Guia de Administração do NGINX Plus.
Persistência de sessão
Com a persistência de sessão, os aplicativos que não podem ser implantados em um cluster podem ter a carga balanceada e ser dimensionados de forma confiável. Os aplicativos que armazenam e replicam o estado da sessão operam com mais eficiência, melhorando o desempenho para o usuário final.
Alguns aplicativos armazenam informações de estado nos servidores upstream, por exemplo, quando um usuário adiciona um item a um carrinho de compras virtual ou edita uma imagem carregada. Nesses casos, pode ser conveniente direcionar todas as solicitações subsequentes desse usuário para o mesmo servidor.
Persistência de sessão especifica para onde uma solicitação deve ser encaminhada, enquanto o balanceamento de carga dá ao NGINX a liberdade de selecionar o servidor upstream ideal. Os dois processos podem coexistir por meio do recurso de persistência de sessão do NGINX Plus:
Se a solicitação corresponder a uma regra de persistência de sessão
então use o servidor upstream de destino
caso contrário aplique o algoritmo de balanceamento de carga para selecionar o servidor upstream
Se a decisão de persistência de sessão falhar porque o servidor de destino não está disponível, o NGINX Plus tomará uma decisão de balanceamento de carga.
O método mais simples de persistência de sessão é a abordagem de “cookie de afinidade”, na qual o NGINX Plus insere um cookie na primeira resposta que identifica o servidor upstream associado:
sticky cookie srv_id expires=1h domain=.example.com path=/;No método alternativo “sticky route”, o NGINX seleciona o servidor upstream com base em parâmetros da solicitação, como o cookie JSESSIONID:
upstream backend {
server backend1.example.com route=a;
server backend2.example.com route=b;
# select first non-empty variable; it should contain either 'a' or 'b'
sticky route $route_cookie $route_uri;
}Para mais informações, consulte o Guia de Administração do NGINX Plus.
Reescrevendo redirecionamentos HTTP
Reescreva os redirecionamentos HTTP se alguns deles não estiverem funcionando, especialmente se você perceber que está sendo redirecionado do proxy para o servidor upstream real.
Ao usar um proxy para acessar um servidor upstream, o servidor disponibiliza a aplicação em um endereço local, mas você a acessa por meio de outro endereço – o endereço do proxy. Esses endereços geralmente são resolvidos como nomes de domínio, e podem surgir problemas se o servidor e o proxy estiverem em domínios diferentes.
Por exemplo, em um ambiente de teste, você pode acessar seu proxy diretamente (pelo endereço IP) ou como localhost. No entanto, o servidor upstream pode estar escutando em um nome de domínio real (como www.nginx.com). Quando o servidor upstream emite uma mensagem de redirecionamento (usando um status 3xx e o cabeçalho Location, ou usando um cabeçalho Refresh), a mensagem pode incluir o domínio real do servidor.
O NGINX tenta interceptar e corrigir as ocorrências mais comuns desse problema. Se você precisar de controle total para forçar reescritas específicas, use a diretiva proxy_redirect da seguinte forma:
proxy_redirect http://staging.mysite.com/ http://$host/;Reescrevendo respostas HTTP
Às vezes, é necessário reescrever o conteúdo de uma resposta HTTP. Talvez, como no exemplo acima, a resposta contenha links absolutos que apontem para um servidor diferente do proxy.
Você pode usar a diretiva sub_filter para definir a reescrita a ser aplicada:
sub_filter /blog/ /blog-staging/;
sub_filter_once off;Uma armadilha muito comum é o uso da compactação HTTP. Se o cliente indicar que aceita dados compactados e o servidor compactar a resposta, o NGINX não poderá inspecioná-la nem modificá-la. A medida mais simples é remover o cabeçalho Accept-Encoding da solicitação do cliente, definindo-o como uma string vazia (""):
proxy_set_header Accept-Encoding "";Um exemplo completo
Veja um modelo de configuração de balanceamento de carga que utiliza todas as técnicas abordadas neste artigo. Os recursos avançados disponíveis no NGINX Plus estão destacados em laranja.
[Editor – A configuração a seguir foi atualizada para usar a API do NGINX Plus para monitoramento de atividades em tempo real e configuração dinâmica de grupos upstream, substituindo os módulos separados usados originalmente.]
server {
listen 80;
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Accept-Encoding "";
proxy_redirect http://staging.example.com/ http://$host/;
# Rewrite the Host header to the value in the client request
proxy_set_header Host $host;
# Replace any references inline to staging.example.com
sub_filter http://staging.example.com/ /;
sub_filter_once off;
}
location /internal-health-check1 {
internal; # Prevent external requests from matching this location block
proxy_pass http://backend;
health_check interval=2s fails=1 passes=5 uri=/test.php match=statusok;
# Explicitly set request parameters; don't use runtime variables
proxy_set_header Host www.example.com;
}
upstream backend {
zone backend 64k; # Use NGINX Plus' shared memory
least_conn;
keepalive 20;
# Apply session persistence for this upstream group
sticky cookie srv_id expires=1h domain=.example.com path=/servlet;
server webserver1 weight=1;
server webserver2 weight=4;
}
match statusok {
# Used for /test.php health check
status 200;
header Content-Type = text/html;
body ~ "Server[0-9]+ is alive";
}
server {
listen 8080;
root /usr/share/nginx/html;
location = /api {
api write=on; # Live activity monitoring and
# dynamic configuration of upstream groups
allow 127.0.0.1; # permit access from localhost
deny all; # deny access from everywhere else
}
}Experimente por conta própria todos os excelentes recursos de balanceamento de carga do NGINX Plus — comece sua avaliação gratuita de 30 dias hoje mesmo ou entre em contato conosco para conversar sobre seus casos de uso.
Sobre o autor

Publicações relacionadas no blog

Como o F5 NGINX One aprimora o gerenciamento e a observabilidade
Descubra como o F5 NGINX One aprimora o gerenciamento e a observabilidade de ambientes híbridos e multicloud ao oferecer um console web centralizado baseado em SaaS, com insights em tempo real, conformidade automatizada e gerenciamento simplificado de configurações.

Do OpenAPI ao NGINX como gateway de API usando uma API declarativa
Descubra como transformar uma definição de esquema OpenAPI em uma configuração NGINX totalmente funcional, operando como um API Gateway com a segurança de um Web Application Firewall e um Portal do Desenvolvedor, usando uma abordagem declarativa de API.

Como gerenciar picos repentinos de tráfego e sobrecarga do servidor
Picos de tráfego e sobrecarga de servidores são preocupações sérias para varejistas online em qualquer época, mas especialmente durante a “Cyber Season” de compras de fim de ano. Detalhamos como você pode aproveitar as soluções de entrega de aplicações de nível de produção da NGINX para se preparar para aumentos repentinos de tráfego.

Distribuição segura de chaves privadas SSL com o NGINX
Descrevemos três maneiras progressivamente mais seguras de proteger chaves privadas SSL ao configurar o NGINX para processar tráfego HTTPS: permitir acesso de leitura apenas ao usuário root, criptografar as chaves com senhas armazenadas separadamente e distribuir as senhas a partir de um repositório central.
Agrupando solicitações de API em lotes com NGINX Plus e o módulo JavaScript do NGINX
O módulo JavaScript do NGINX lançado com o NGINX Plus R15 oferece suporte a subsolicitações, possibilitando uma classe totalmente nova de casos de uso para o NGINX Plus. Este exemplo completo também usa a API do NGINX Plus e os módulos de chave-valor para converter solicitações de API dos clientes em solicitações separadas para as APIs dos microsserviços que compõem um aplicativo.
Como superar o esgotamento de portas efêmeras no NGINX e no NGINX Plus
Confira dicas para evitar o esgotamento de portas efêmeras com ajustes no kernel do Linux, conexões keepalive e conexões vinculadas dinamicamente a endereços IP locais.