Como reduzir o número de soquetes em TIME_WAIT?

35

Ubuntu Server 10.04.1 x86

Eu tenho uma máquina com um serviço HTTP FCGI por trás do nginx, que atende muitas solicitações HTTP pequenas para vários clientes diferentes. (Cerca de 230 solicitações por segundo nas horas de pico, o tamanho médio da resposta com cabeçalhos é de 650 bytes, vários milhões de clientes diferentes por dia).

Como resultado, tenho muitos soquetes pendurados em TIME_WAIT (o gráfico é capturado com as configurações TCP abaixo):

Eu gostaria de reduzir o número de soquetes.

O que posso fazer além disso?

$ cat /proc/sys/net/ipv4/tcp_fin_timeout
1
$ cat /proc/sys/net/ipv4/tcp_tw_recycle
1
$ cat /proc/sys/net/ipv4/tcp_tw_reuse
1

Atualização: alguns detalhes sobre o layout real do serviço na máquina:

client -----TCP-socket--> nginx (load balancer reverse proxy) 
       -----TCP-socket--> nginx (worker) 
       --domain-socket--> fcgi-software
                          --single-persistent-TCP-socket--> Redis
                          --single-persistent-TCP-socket--> MySQL (other machine)

Provavelmente devo mudar o balanceador de carga - > conexão de trabalho para soquetes de domínio também, mas o problema sobre soquetes TIME_WAIT permaneceria - planejo adicionar um segundo trabalhador em uma máquina separada em breve. Não será possível usar soquetes de domínio nesse caso.

    
por Alexander Gladysh 13.12.2010 / 18:15

2 respostas

28

Uma coisa que você deve fazer para começar é corrigir o net.ipv4.tcp_fin_timeout=1 . Isso é muito baixo, você provavelmente não deve ter muito menos que 30.

Como isso está por trás do nginx. Isso significa que o nginx está agindo como um proxy reverso? Se esse for o caso, suas conexões serão 2x (uma para o cliente, uma para seus servidores da web). Você sabe a que extremidade esses soquetes pertencem?

Update:
fin_timeout é quanto tempo eles ficam em FIN-WAIT-2 (De networking/ip-sysctl.txt na documentação do kernel):

tcp_fin_timeout - INTEGER
        Time to hold socket in state FIN-WAIT-2, if it was closed
        by our side. Peer can be broken and never close its side,
        or even died unexpectedly. Default value is 60sec.
        Usual value used in 2.2 was 180 seconds, you may restore
        it, but remember that if your machine is even underloaded WEB server,
        you risk to overflow memory with kilotons of dead sockets,
        FIN-WAIT-2 sockets are less dangerous than FIN-WAIT-1,
        because they eat maximum 1.5K of memory, but they tend
        to live longer. Cf. tcp_max_orphans.

Eu acho que você talvez tenha que deixar o Linux manter o número do socket TIME_WAIT contra o que parece ser 32k para eles e é aí que o Linux os recicla. Esses 32k são mencionados neste link :

Also, I find the /proc/sys/net/ipv4/tcp_max_tw_buckets confusing. Although the default is set at 180000, I see a TCP disruption when I have 32K TIME_WAIT sockets on my system, regardless of the max tw buckets.

Este link também sugere que o estado TIME_WAIT é de 60 segundos e não pode ser ajustado via proc.

Fato divertido aleatório:
Você pode ver os timers no timewait com netstat para cada soquete com netstat -on | grep TIME_WAIT | less

Reuse Vs Recycle:
Estes são interessantes, lida como reutilização, permite a reutilização de sockets time_Wait e recicla coloca no modo TURBO:

tcp_tw_recycle - BOOLEAN
        Enable fast recycling TIME-WAIT sockets. Default value is 0.
        It should not be changed without advice/request of technical
        experts.

tcp_tw_reuse - BOOLEAN
        Allow to reuse TIME-WAIT sockets for new connections when it is
        safe from protocol viewpoint. Default value is 0.
        It should not be changed without advice/request of technical
        experts.

Eu não recomendaria usar net.ipv4.tcp_tw_recycle, pois isso causa problemas com os clientes NAT .

Talvez você possa tentar não ter os dois ligados e ver que efeito tem (tente um de cada vez e veja como eles funcionam por conta própria)? Eu usaria netstat -n | grep TIME_WAIT | wc -l para feedback mais rápido do que Munin.

    
por 13.12.2010 / 19:31
1

tcp_tw_reuse é relativamente seguro, pois permite que as conexões TIME_WAIT sejam reutilizadas.

Além disso, você pode executar mais serviços ouvindo em portas diferentes, atrás do balanceador de carga, se a falta de portas for um problema.

    
por 09.09.2014 / 17:56