Com nginx keepalive Reduzo os custos de estabelecimento de ligação, diminuo os handshakes e acelero sensivelmente os tempos de resposta. Tempos de espera ajustados de forma específica, limites de pedidos por ligação e sockets upstream reutilizados proporcionam ganhos de desempenho mensuráveis sem necessidade de novo hardware.
Pontos centrais
- Intervalos Escolher de forma sensata: o tempo de inatividade deve ser tão curto quanto necessário e tão longo quanto útil.
- Pedidos Limitar por ligação: Sockets duradouros, sem travamentos.
- Grupos a montante Ativar: ligações persistentes ao backend por trabalhador.
- Trabalhador e ajustar as ligações: slots suficientes para clientes inativos e ativos.
- Monitorização Estabelecer: monitorizar a taxa de ligação, a latência e os erros.
NGINX Keepalive: Efeitos e custos
Mantenho as ligações TCP abertas de forma deliberada, porque Apertos de mão são dispendiosas e predominam em muitas pequenas solicitações. Os sockets persistentes não só poupam RTTs, como também uniformizam a carga da CPU, uma vez que a criptografia para o TLS é executada com menos frequência. No entanto, cada ligação aberta ocupa Recursos, como descritores de ficheiros e buffers, que tenho de manter sob controlo. O segredo está no equilíbrio: reutilização suficiente para garantir a velocidade, e recursos suficientes para estabelecer novas ligações em picos de tráfego. Quem conseguir equilibrar estes aspetos consegue valores de TTFB consistentemente baixos e uma experiência de utilizador rápida.
HTTP/2 e HTTP/3: o multiplexing aliado ao keepalive
Com HTTP/2 e HTTP/3 O número de ligações necessárias por cliente diminui, uma vez que vários fluxos passam por uma única linha. No entanto, o Keepalive continua a ser relevante: essa ligação deve permanecer aberta de forma fiável; caso contrário, a vantagem da multiplexação perde-se devido às frequentes reconexões.
Presto atenção aos parâmetros de inatividade específicos para protocolos modernos e certifico-me de que os valores correspondem aos meus tempos limite do cliente. Para os testes, começo com valores moderados e vou aumentando, à medida que a carga se mantém estável, até que a taxa de reconexão diminua e as latências se mantenham constantes.
http {
# HTTP/2: tempo de inatividade para fluxos não utilizados, mas abertos
http2_idle_timeout 60s;
# HTTP/3/QUIC: lógica semelhante para ligações baseadas em UDP
http3_idle_timeout 60s;
# A retomada de sessão TLS reduz os custos do handshake em novas ligações
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1d;
ssl_session_tickets off;
}
O multiplexing reduz o número necessário de ligações TCP/QUIC paralelas, mas não a importância da tempos de espera corretos. Quem utiliza o HTTP/2/3 pode, muitas vezes, definir os tempos de espera do cliente de forma um pouco mais generosa, uma vez que muitos recursos pequenos circulam pelo mesmo canal. Importante: continuar a ser mensurável Tempo para o primeiro byte, taxas de erro e fluxos abertos por ligação.
Configurar corretamente o Client-Keepalive
No caso dos clientes de navegador, controlo a reutilização através de tempo de espera de keepalive e keepalive_requests, para que as ligações permaneçam ativas durante tempo suficiente sem ficarem bloqueadas indefinidamente. Como ponto de partida, utilizo um tempo de espera de 30 a 60 segundos e 100 a 300 pedidos por ligação; depois, vou ajustando com base nas métricas. Este artigo fornece uma análise detalhada Guia sobre o tempo de espera do Keepalive, que explica o impacto na latência e nos recursos do servidor. Os tempos de espera mais curtos são adequados para um grande número de chamadas curtas, enquanto os intervalos mais longos são úteis para acessos periódicos à API. Para começar, defino valores predefinidos claros e avalio o impacto nas ligações abertas, bem como nos padrões de erros.
http {
# Ligações inativas com o cliente
keepalive_timeout 60s;
# Limite máximo de pedidos por ligação TCP
keepalive_requests 200;
# Opcional: desativar o Keep-Alive para determinados clientes (erros herdados)
# keepalive_disable msie6;
}
Keepalive a montante no proxy reverso
Entre o NGINX e as aplicações de backend, utilizo sockets upstream persistentes, porque a ligação ao PHP-FPM, ao Node.js ou aos serviços Python também Latência custa. Para tal, ativo no pool upstream um número adequado de ligações reutilizáveis por trabalhador. É importante utilizar HTTP/1.1 na resposta e um cabeçalho „Connection“ vazio; caso contrário, o pedido «close» do cliente interrompe a persistência do backend. Baseio-me no número de pedidos simultâneos e configuro o pool de forma a que quase não ocorram novas ligações. Desta forma, o tempo de ligação do backend diminui e toda a cadeia proporciona um desempenho mais ágil Respostas.
upstream backend {
server 127.0.0.1:9000;
keepalive 64; # Número de ligações persistentes upstream por trabalhador
}
server {
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
# Keepalive TCP para sockets de upstream ao nível do sistema operativo
proxy_socket_keepalive on;
}
}
Dimensionamento do conjunto e orçamento de ligações
Calculo os pools de forma realista: o número de ligações persistentes a montante resulta de worker_processes × keepalive por upstream. Quem utilizar 8 workers e um keepalive de 64 mantém abertos até 512 sockets por upstream – por instância. Atrás de um balanceador de carga ou com vários destinos upstream, esse número pode aumentar rapidamente.
O meu valor-alvo: sockets abertos suficientes para que a maior parte dos pedidos sem o novo Connect é atendida, mas ainda há margem para picos. Observo a métrica „novas ligações de upstream por segundo“ e vou reduzindo-a até que novos aumentos no tamanho do pool deixem de trazer melhorias significativas na latência.
Também tenho em conta Equidade: As piscinas demasiado grandes podem prejudicar os clientes recém-chegados, uma vez que os slots dos trabalhadores ocupam ligações inativas. Um limite moderado, acompanhado de uma monitorização ativa, é geralmente mais rápido do que valores máximos definidos por suposição.
Ajuste fino: tempos limite e limites de pedidos
Combino o tempo de espera e o limite de pedidos de forma a que as ligações sejam efetivamente reutilizadas, sem que isso leve ao Esquiador de fundo . Valores elevados em ambos os eixos minimizam as ligações, mas aumentam o risco de sockets ficarem pendentes em caso de problemas de rede. Valores baixos garantem ligações recentes, mas implicam handshakes adicionais. Vou avançando aos poucos, observando os erros e ajustando periodicamente. A tabela seguinte apresenta intervalos iniciais adequados para diferentes padrões de utilização e fornece uma visão compacta Orientação.
| Cenário | tempo de espera de keepalive | keepalive_requests | Nota |
|---|---|---|---|
| Muitas visualizações de páginas curtas | 10–30 s | 100-300 | Reutilização rápida, baixo consumo em modo inativo |
| Site típico | 60–120 s | 200–400 | Um bom nível médio para Assets e HTML |
| API com chamadas periódicas | 60–120 s | 300–1000 | Maior taxa de reutilização para os clientes |
| Serviços internos / Gateways | 30–90 s | 500–1000+ | A consistência é mais importante do que um número mínimo de ligações |
Ajuste dos trabalhadores e ligações
Coloquei processos_trabalhadores em «auto» ou no número de núcleos da CPU e planeia o suficiente ligações_trabalhadores porque os sockets inativos ocupam slots. Limites demasiado baixos impedem novas aceitações, apesar de ainda haver capacidade de CPU disponível. Quem utiliza pools de keepalive elevadas precisa de descritores e slots de eventos suficientes por cada worker. Uma boa introdução é fornecida por „Escalar as ligações dos trabalhadores“, que explica as relações entre eventos, ligações e carga. Valores cuidadosamente definidos garantem que a reutilização em modo inativo e as novas ligações possam coexistir.
worker_processes auto;
events {
worker_connections 4096;
# Opcional: a opção «reuseport» pode melhorar a distribuição ao nível do kernel
# multi_accept on;
}
http {
keepalive_timeout 60s;
keepalive_requests 200;
upstream backend {
server 127.0.0.1:9000;
keepalive 64;
}
}
Otimização do sistema operativo e dos sockets
Estou a verificar os limites do sistema para que o Keepalive possa atingir o seu pleno potencial. Um número insuficiente de descritores ou filas de sockets muito curtas provocam estrangulamentos artificiais. Para além do ulimit e do worker_rlimit_nofile, os limites do kernel são fundamentais.
# Valores de sysctl exemplificativos (ajustar com cuidado e após realizar testes)
fs.file-max = 1000000
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 16384
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_max_syn_backlog = 262144
Calibro estes valores em função do ambiente: muitas ligações de curta duração beneficiam de um intervalo de portas mais alargado e de tempos FIN/TIME_WAIT mais curtos. No caso do keepalive a montante, reduzo Neuconnects, o que reduz as pressões do TIME_WAIT. Além disso, tenho em conta NAT- Equipamentos entre o proxy e o backend: tempos de espera em inatividade demasiado agressivos na rede cortam as ligações de forma imprevisível. Um limite moderado de pedidos por socket e keepalives TCP (proxy_socket_keepalive on;) evitam ligações „estagnadas“.
Definir corretamente o cabeçalho e a versão HTTP
Presto atenção a HTTP/1.1 para o backend, porque o Upstream-Keepalive só funciona assim. Além disso, removo o controlo ativo das ligações através do cabeçalho, para que o NGINX gere a persistência de forma autónoma. Do lado do cliente, deixo o Keep-Alive a funcionar de acordo com a norma e limito o tempo de vida através do timeout e do limite de pedidos. Além disso, verifico os timeouts de inatividade do backend e defino-os ligeiramente acima dos valores do NGINX, para evitar erros de reinicialização. Cabeçalhos bem definidos garantem a Reutilização sem encerramentos indesejados.
Exemplo #: Localização do proxy com cabeçalhos corretos
location /api/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
Diferenciação: HTTP Keep-Alive vs. TCP Keep-Alive
Faço uma distinção rigorosa entre HTTP Keep-Alive (várias solicitações HTTP por ligação) e TCP-Keepalive (Testes ao nível do sistema operativo para detetar terminais inativos). Controlo o HTTP Keep-Alive com tempo de espera de keepalive e keepalive_requests, enquanto os keepalives do TCP, dependendo da pilha, podem ser de proxy_socket_keepalive on; e os parâmetros do sistema. Para backends que utilizam redes instáveis, ativo os keepalives do TCP para limpar mais rapidamente os sockets bloqueados.
Aplicações de longa duração e casos especiais: WebSockets, SSE, gRPC
WebSockets e eventos enviados pelo servidor são Esquiador de fundo, que mantêm uma ligação aberta durante muito tempo – neste caso, a Reuse clássica desempenha um papel secundário. Eu garanto que haja tempo_limite_de_leitura_proxy e protege-me com tempo_limite_de_envio contra Slowloris-Efeitos. No caso do gRPC (baseado em HTTP/2), aplicam-se as considerações relativas à multiplexação; configuro os tempos de espera de inatividade de forma a que os fluxos não sejam encerrados desnecessariamente.
location /ws/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 300s;
send_timeout 30s;
}
Monitorização e métricas
Mido o sucesso através de indicadores como a taxa de novas ligações upstream, upstream_connect_time e a percentagem de ligações abertas por cada worker. A diminuição das taxas de ligação, com o número de pedidos a manter-se estável ou a aumentar, indica uma reutilização bem-sucedida. Tempos de espera ou reinicializações de ligação anormais sinalizam tempos de espera contraditórios entre o NGINX e o backend. Além disso, observo a memória, os descritores de ficheiros e as filas de eventos sob carga. Quem verifica regularmente identifica tendências numa fase precoce e evita custos elevados Falhas.
Melhorias no registo para uma maior transparência na reutilização
Para obter mais informações, vou adicionar detalhes sobre as ligações ao registo de acesso. Assim, consigo perceber com que frequência uma ligação TCP é reutilizada e como evoluem os tempos de ligação.
log_format keepalive_fmt
'$remote_addr $host "$request" $status $body_bytes_sent '
'$request_time $upstream_connect_time '
'conn:$connection reqs:$connection_requests';
access_log /var/log/nginx/access_keepalive.log keepalive_fmt;
Estou a analisar os valores da mediana e dos percentis P95/P99 de upstream_connect_time bem como a distribuição de $ pedidos de ligação. O aumento do número de repetições, com uma latência estável, significa que os conjuntos e os tempos limite foram escolhidos de forma adequada.
Obstáculos e soluções típicos
As pilhas demasiado grandes ocupam as ranhuras de ligação, enquanto novos clientes ficam à espera; por isso, mantenho os tamanhos moderados e vou ajustando. Tempos de espera em inatividade diferentes entre o proxy e o backend provocam reinicializações; por isso, defino o backend com um valor ligeiramente superior ao NGINX. Um „Connection: close“ esquecido no cabeçalho do proxy interrompe a persistência; por isso, esvazio o cabeçalho de forma sistemática. A negociação TLS pode sobrecarregar a CPU quando há muitas novas ligações, o que atenuei aumentando a taxa de reutilização. Em caso de falhas esporádicas na rede, um limite moderado de pedidos por socket ajuda a garantir que as antigas Sessões não viveremos para sempre.
Configurações orientadas para a prática
Para sites com muito tráfego, opto por um tempo de espera curto e um limite de pedidos médio-alto, para que os recursos funcionem de forma eficiente. No caso de APIs com chamadas recorrentes, aumentei o limite para reduzir ainda mais os handshakes TCP e TLS. Dimensiono os pools de upstream com base no paralelismo esperado e testo com tráfego realista. Cada ambiente comporta-se de forma diferente, por isso verifico a latência e os padrões de erros após quaisquer alterações. Dois exemplos ilustram isto: Valores iniciais, que depois aperfeiçoo com métricas.
# Cenário 1: Site com elevado tráfego
http {
keepalive_timeout 30s;
keepalive_requests 300;
upstream app {
server 127.0.0.1:8080;
keepalive 32;
}
server {
listen 443 ssl http2;
Acompanhar o tempo de inatividade HTTP/2 (#)
http2_idle_timeout 45s;
}
}
# Cenário 2: API com chamadas periódicas
http {
keepalive_timeout 75s;
keepalive_requests 1000;
upstream api_backend {
server 127.0.0.1:9001;
keepalive 64;
}
server {
listen 443 ssl http2;
# Janela de inatividade ligeiramente mais longa para chamadas recorrentes
http2_idle_timeout 75s;
}
}
Lista de verificação para a otimização iterativa
Começo por fazer uma análise da situação atual: os padrões de tráfego, os tempos de resposta e a taxa de erros ditam o ritmo. Em seguida, defino o tempo limite do cliente e o limite de pedidos com valores iniciais sólidos e ativo os conjuntos de servidores a montante. Defino os tempos limite de inatividade do backend um pouco mais altos do que no NGINX, para evitar que ocorram Reinicializações ocorrer. Em seguida, monitorizo as taxas de ligação, o tempo de ligação e os sockets abertos por trabalhador. Quem quiser aprofundar o tema do grau de reutilização encontrará sugestões sobre Reutilização de ligações e limites máximos razoáveis.
Diagnóstico adicional: incompatibilidades e comportamento temporal
Quando as ligações parecem interromper-se „sem motivo aparente“, procuro Incompatibilidades na cadeia: inatividade do cliente vs. tempo de espera do NGINX vs. inatividade do backend e NAT/gateways intermédios. Aumento ligeiramente o tempo de espera do backend para um valor ligeiramente superior ao do NGINX, verifico os códigos de reinicialização no registo de erros e observo se upstream_connect_time Mostra picos. Muitas vezes, basta uma pequena margem de segurança (por exemplo, +10–20%) no tempo limite do backend para eliminar os reinícios.
Além disso, tenho em conta que „abraço demorado“Fases de encerramento: ao encerrar uma ligação, o NGINX permite que os dados recebidos sejam transmitidos durante um breve período, o que ocupa recursos dos workers. Um número muito elevado de encerramentos simultâneos pode bloquear eventos. Nesses casos, calibro as janelas de tempo de encerramento e mantenho o número total de ligações abertas equilibrado, definindo valores adequados para o keepalive.».
Resumo: O Keepalive como alavanca de desempenho
Utilizo o Keepalive de forma seletiva, porque reduz os custos de estabelecimento de ligação, diminui a latência e alivia a carga da CPU. A combinação de um tempo de espera adequado, um limite de pedidos bem definido e conjuntos de servidores upstream adequados traz benefícios percetíveis Velocidade. Sem monitorização, o potencial fica por explorar; por isso, analiso continuamente os indicadores e ajusto os valores passo a passo. Quem precisar de reservas adicionais deve prestar atenção ao número de workers, aos slots de ligação e ao tratamento correto dos cabeçalhos. Configurações profissionais, por exemplo, em webhoster.de, tiram o máximo partido destes recursos e prestam serviços rápidos e fiáveis.


