NGINX tempo limite após +200 conexões simultâneas

12

Este é o meu nginx.conf (atualizei a configuração para garantir que não haja nenhum PHP envolvido ou nenhum outro afunilamento):

user                nginx;
worker_processes    4;
worker_rlimit_nofile 10240;

pid                 /var/run/nginx.pid;

events
{
    worker_connections  1024;
}

http
{
    include             /etc/nginx/mime.types;

    error_log           /var/www/log/nginx_errors.log warn;

    port_in_redirect    off;
    server_tokens       off;
    sendfile            on;
    gzip                on;

    client_max_body_size 200M;

    map $scheme $php_https { default off; https on; }

    index index.php;

    client_body_timeout   60;
    client_header_timeout 60;
    keepalive_timeout     60 60;
    send_timeout          60;

    server
    {
        server_name dev.anuary.com;

        root        "/var/www/virtualhosts/dev.anuary.com";
    }
}

Estou usando o link para testar meu servidor (comprei o plano de 10.000 conexões simultâneas). Em uma execução de 30 segundos, recebo 964 hits e 5,587 timeouts . O primeiro tempo esgotado aconteceu em 40,77 segundos no teste quando o número de usuários simultâneos estava em 200.

Durante o teste, a carga do servidor foi ( top output):

 PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                               20225 nginx     20   0 48140 6248 1672 S 16.0  0.0   0:21.68 nginx                                                                  
    1 root      20   0 19112 1444 1180 S  0.0  0.0   0:02.37 init                                                                   
    2 root      20   0     0    0    0 S  0.0  0.0   0:00.00 kthreadd                                                               
    3 root      RT   0     0    0    0 S  0.0  0.0   0:00.03 migration/0      

Portanto, não é um problema de recurso do servidor. O que é então?

ATUALIZAÇÃO 2011 12 09 GMT 17:36.

Até agora, fiz as seguintes alterações para garantir que o gargalo não seja TCP / IP. Adicionado a /etc/sysctl.conf :

# These ensure that TIME_WAIT ports either get reused or closed fast.
net.ipv4.tcp_fin_timeout = 1
net.ipv4.tcp_tw_recycle = 1
# TCP memory
net.core.rmem_max = 16777216
net.core.rmem_default = 16777216
net.core.netdev_max_backlog = 262144
net.core.somaxconn = 4096

net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_orphans = 262144
net.ipv4.tcp_max_syn_backlog = 262144
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 2

Mais algumas informações de depuração:

[root@server node]# ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 126767
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 1024
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

NB Esse worker_rlimit_nofile está definido como 10240 nginx config.

ATUALIZAÇÃO 2011 12 09 GMT 19:02.

Parece que quanto mais mudanças eu faço, pior fica, mas aqui o novo arquivo de configuração.

user                nginx;
worker_processes    4;
worker_rlimit_nofile 10240;

pid                 /var/run/nginx.pid;

events
{
    worker_connections  2048;
    #1,353 hits, 2,751 timeouts, 72 errors - Bummer. Try again?
    #1,408 hits, 2,727 timeouts - Maybe you should increase the timeout?
}

http
{
    include             /etc/nginx/mime.types;

    error_log           /var/www/log/nginx_errors.log warn; 

    # http://blog.martinfjordvald.com/2011/04/optimizing-nginx-for-high-traffic-loads/
    access_log              off;

    open_file_cache         max=1000;
    open_file_cache_valid   30s;

    client_body_buffer_size 10M;
    client_max_body_size    200M;

    proxy_buffers           256 4k;
    fastcgi_buffers         256 4k;

    keepalive_timeout       15 15;

    client_body_timeout     60;
    client_header_timeout   60;

    send_timeout            60;

    port_in_redirect        off;
    server_tokens           off;
    sendfile                on;

    gzip                    on;
    gzip_buffers            256 4k;
    gzip_comp_level         5;
    gzip_disable            "msie6";



    map $scheme $php_https { default off; https on; }

    index index.php;



    server
    {
        server_name ~^www\.(?P<domain>.+);
        rewrite     ^ $scheme://$domain$request_uri? permanent;
    }

    include /etc/nginx/conf.d/virtual.conf;
}

ATUALIZAÇÃO 2011 12 11 GMT 20:11.

Esta é a saída de netstat -ntla durante o teste.

link

ATUALIZAÇÃO 2011 12 12 GMT 10:54.

Só para esclarecer, o iptables (firewall) está desativado durante o teste.

ATUALIZAÇÃO 2011 12 12 GMT 22:47.

Este é o sysctl -p | grep mem dump.

net.ipv4.ip_forward = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
kernel.sysrq = 0
kernel.core_uses_pid = 1
net.ipv4.tcp_syncookies = 1
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 30
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_mem = 8388608 8388608 8388608
net.ipv4.tcp_rmem = 4096 87380 8388608
net.ipv4.tcp_wmem = 4096 65536 8388608
net.ipv4.route.flush = 1
net.ipv4.ip_local_port_range = 1024 65000
net.core.rmem_max = 16777216
net.core.rmem_default = 16777216
net.core.wmem_max = 8388608
net.core.wmem_default = 65536
net.core.netdev_max_backlog = 262144
net.core.somaxconn = 4096
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_orphans = 262144
net.ipv4.tcp_max_syn_backlog = 262144
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 2

ATUALIZAÇÃO 2011 12 12 GMT 22:49

Estou usando blitz.io para executar todos os testes. A URL que estou testando é link , usando o seguinte comando: --region ireland --pattern 200-250:30 -T 1000 http://dev.anuary.com/test.txt

ATUALIZAÇÃO 2011 12 13 GMT 13:33

nginx limites do usuário (definidos em /etc/security/limits.conf ).

nginx       hard nofile 40000
nginx       soft nofile 40000
    
por Guy 13.12.2011 / 14:35

5 respostas

2

Você precisará descarregar suas conexões de rede durante o teste. Enquanto o servidor pode ter carga quase zero, sua pilha TCP / IP pode estar faturando. Procure por conexões TIME_WAIT em uma saída netstat.

Se este for o caso, então você deverá verificar o ajuste dos parâmetros do kernel tcp / ip relacionados aos estados de Espera TCP, Reciclagem TCP e métricas similares.

Além disso, você não descreveu o que está sendo testado.

Eu sempre testo:

  • conteúdo estático (imagem ou arquivo de texto)
  • página php simples (phpinfo por exemplo)
  • página do aplicativo

Isso pode não se aplicar ao seu caso, mas é algo que eu faço quando estou testando o desempenho. Testar diferentes tipos de arquivos pode ajudá-lo a identificar o obstáculo.

Mesmo com conteúdo estático, testar tamanhos diferentes de arquivos também é importante para que os tempos limite e outras métricas sejam discados.

Temos algumas caixas Nginx de conteúdo estático que lidam com mais de 3000 conexões ativas. Então, o Nginx certamente pode fazer isso.

Atualização: Seu netstat mostra muitas conexões abertas. Pode querer tentar ajustar sua pilha TCP / IP. Além disso, qual arquivo você está solicitando? O Nginx deve fechar rapidamente a porta.

Aqui está uma sugestão para sysctl.conf:

net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.tcp_rmem = 4096 87380 8388608
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 30
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1

Estes valores são muito baixos, mas eu tive sucesso com eles em caixas Nginx de alta concorrência.

    
por 09.12.2011 / 17:47
1

Ainda outra hipótese. Você aumentou worker_rlimit_nofile , mas o número máximo de clientes é definido na documentação como

max_clients = worker_processes * worker_connections

E se você tentar aumentar worker_connections para 8192? Ou, se houver núcleos de CPU suficientes, aumente worker_processes ?

    
por 15.12.2011 / 06:52
1

Eu estava tendo um problema muito parecido com uma caixa nginx que serve como balanceador de carga com um upstream de servidores apache.

No meu caso, eu pude isolar o problema relacionado à rede, pois os servidores apache upstream ficaram sobrecarregados. Eu poderia recriá-lo com scripts bash simples enquanto o sistema geral estava sob carga. De acordo com uma sequência de um dos processos suspensos, a chamada de conexão estava recebendo um ETIMEDOUT.

Essas configurações (nos servidores nginx e upstream) eliminaram o problema para mim. Eu estava recebendo 1 ou 2 timeouts por minuto antes de fazer essas alterações (caixas de tratamento de ~ 100 reqs / s) e agora obter 0.

net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_fin_timeout = 20
net.ipv4.tcp_max_syn_backlog = 20480
net.core.netdev_max_backlog = 4096
net.ipv4.tcp_max_tw_buckets = 400000
net.core.somaxconn = 4096

Eu não recomendaria usar net.ipv4.tcp_tw_recycle ou net.ipv4.tcp_tw_reuse, mas se você quiser usar um, vá com o último. Eles podem causar problemas bizarros se houver algum tipo de latência e o último é, no mínimo, o mais seguro dos dois.

Acho que definir tcp_fin_timeout como 1 acima pode causar alguns problemas também. Tente colocá-lo em 20/30 - ainda muito abaixo do padrão.

    
por 31.12.2011 / 22:52
0

talvez não seja problema nginx, enquanto você testa em blitz.io fazer um:

tail -f /var/log/php5-fpm.log

(é isso que eu estou usando para lidar com o php)

isso dispara um erro e os tempos limite começam a aumentar:

WARNING: [pool www] server reached pm.max_children setting (5), consider raising it

então, coloque mais max_children no fmp conf e pronto! ; D

    
por 24.04.2012 / 08:39
0

Você tem um max open files (1024) muito baixo, tente alterar e reinicie o nginx. ( cat /proc/<nginx>/limits para confirmar)

ulimit -n 10240

E aumente worker_connections para 10240 ou superior.

    
por 27.01.2015 / 10:26