Aumentando o desempenho do nginx após 1k req / s

1

Estou tentando escalar uma instalação nginx com o melhor de sua capacidade.

Estou executando uma instância nginx com 6 processos_de_operadores (6 núcleos) e 5 servidores de backend consistindo em uwsgi configuração com 10 funcionários cada. (total de 50 trabalhadores).

No entanto, qualquer referência que eu tentei com parâmetros diferentes (usando ab ) para conexões totais e simultâneas parece sair por volta de 1000 solicitações / segundo.

Desativei todos os registros para nginx e uwsgi (para evitar lentidão devido a problemas de disco). Eu estou testando contra um aplicativo python Flask que simplesmente envia {'status':'ok'} de volta. Sem acesso ao banco de dados, sem cálculos, nada.

A parte relevante da configuração do nginx tem esta aparência:

    user www-data;
    worker_processes 6;
    worker_rlimit_nofile 100000;
    pid /var/run/nginx.pid;

    events {
            use epoll;
            worker_connections 2048;
            multi_accept on;
    }

    http {

            ##
            # Basic Settings
            ##

            sendfile on;
            tcp_nopush on;
            tcp_nodelay on;
            keepalive_timeout 65;
            types_hash_max_size 2048;
            # server_tokens off;

            # server_names_hash_bucket_size 64;
            # server_name_in_redirect off;

            include /etc/nginx/mime.types;
            default_type application/octet-stream;

            ##
            # Logging Settings
            ##

            access_log off; # /var/log/nginx/access.log;
            error_log /var/log/nginx/error.log;

            <...>
    }

Eu estou procurando por alguma dica, qualquer coisa que eu tenha esquecido, para aumentar a taxa de transferência. Analisando as estatísticas de cada uwsgi pool (usando uwsgitop ) elas não parecem, em momento algum, difíceis de executar, o que me leva a acreditar que o nginx é o gargalo. Além disso, o desempenho foi o mesmo com um único grupo de trabalhadores em vez de 10. Além disso, htop também mostra que não estou nem perto do máximo em termos de memória ou CPU.

    
por Christian P. 02.10.2014 / 16:40

3 respostas

2

Eu recomendo que você instale o pacote sysstat e, em seguida, verifique as informações gravadas com sar .

sar -n SOCK -s <start_time> -e <end_time> para obter a quantidade de soquetes durante o benchmark

sar -n DEV -s <start_time> -e <end_time> para obter pacotes de interfaces de rede e largura de banda

sar -d -s <start_time> -e <end_time> para obter estatísticas de io por dispositivo

sar -v -s <start_time> -e <end_time> para obter o número de identificadores de arquivo e inodes

etc

Verifique os limites de segurança para seus usuários (número máximo de arquivos abertos, número máximo de processos, etc.).

Em seguida, verifique as configurações do kernel: intervalo de portas local, somaxconn, txqueue de dispositivo, netdev backlog, ativar soquete de reciclagem para TIME_WAIT, se necessário (em relação a tcp-tw com sar -n SOCK) com SO_LINGER em nginx ou tcp_tw_recycle (se você não tem NAT) ou reutiliza (para conexões de saída), altere a quantidade de tw_buckets se necessário, certifique-se de que o sack / dsack e os registros de data e hora estejam ativados, reduza o tempo limite FIN_WAIT_2, aumente as manipulações máximas se necessário etc.

Pode haver muitos fatores.

Antes de verificar tudo isso, certifique-se de não executar ab no mesmo equipamento e que o aplicativo python tenha bons tempos de resposta.

E um teste simples para garantir que o aplicativo python não seja o culpado: o mesmo benchmark em um arquivo estático diretamente do servidor pelo nginx.

    
por 02.10.2014 / 17:36
1

Além das outras duas respostas aqui, o conntrack (rastreamento de conexão) também pode ser um problema. Se você estiver usando Linux e estiver usando netfilter (ou seja, iptables), sua tabela conntrack pode estar cheia.

Primeiro verifique se o conntrack está ativado. Por exemplo:

$ /sbin/lsmod | grep conntrack
ip_conntrack           51617  1 xt_state

$ lsmod | grep -i con
nf_conntrack_ipv4      19159  5 
nf_defrag_ipv4         12729  1 nf_conntrack_ipv4
nf_conntrack           92358  5 xt_state,iptable_nat,nf_conntrack_ipv4,nf_nat_ipv4,nf_nat

A saída irá variar de acordo com a versão do kernel.

Se, se um dos módulos nf_conntrack ou ip_conntrack for carregado, você poderá ver quantas entradas do conntrack existem e verificar qual é o seu máximo com o seguinte:

Red Hat (RHEL, CentOS, Fedora, etc):

$ sudo wc -l /proc/net/ip_conntrack
$ /sbin/sysctl -a | grep conntrack_max

or

$ sudo wc -l /proc/net/nf_conntrack
$ /sbin/sysctl -a | grep conntrack_max

Debian:

$ cat /proc/sys/net/netfilter/nf_conntrack_count
$ /sbin/sysctl -a | grep conntrack_max

Se você tiver preenchido a tabela conntrack, precisará aumentar o limite via sysctl ou /etc/sysctl.conf.

Nota : o conntrack não se aplica apenas ao servidor. Você precisará verificar cada ponto entre você e o servidor: computador cliente, balanceador de carga (nginx), servidor upstream (backend) e possivelmente até mesmo qualquer roteador.

    
por 02.10.2014 / 19:12
1

Eu examinaria os descritores de arquivos, possível saturação de rede / interface e problemas de IO.

Para ver se a interface de rede está saturada, use iptraf, que é uma ferramenta de linha de comando para visualizar as estatísticas em tempo real. Simplesmente:

iptraf

Para problemas de IO use iostat

iostat 1

que mostrará o uso do IO e carregará a cada 1 segundo.

Para problemas no descritor de arquivo, use lsof ou / proc:

lsof -P -n -p <PID> | wc -l
ls /proc/<PID>/fd | wc -l

Use o comando ulimit -a | grep files (como o usuário que executa o processo) para verificar quantos arquivos você tem permissão para abrir. O padrão é 1024.

Veja esta página para mais informações: link

Veja esta pergunta para o problema do descritor de arquivo específico nginx, que pode muito bem estar relacionado com o seu problema: compreendendo os descritores de arquivos máximos para o linux e nginx e melhor valor para worker_rlimit_nofile

    
por 02.10.2014 / 17:03