Limit czasu NGINX po +200 jednoczesnych połączeniach

12

To jest moje nginx.conf(zaktualizowałem konfigurację, aby upewnić się, że nie jest zaangażowany PHP ani żadne inne wąskie gardła):

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";
    }
}

Korzystam z http://blitz.io/play, aby przetestować mój serwer (kupiłem plan 10 000 równoczesnych połączeń). W 30 sekundowym biegu dostaję 964trafienia i 5,587 timeouts. Pierwsze przekroczenie limitu czasu miało miejsce w teście w 40,77 sekundy, gdy liczba równoczesnych użytkowników wynosiła 200.

Podczas testu obciążenie serwera było ( topdane wyjściowe):

 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      

Dlatego nie jest to problem z zasobami serwera. Co to jest?

AKTUALIZACJA 2011 12 09 GMT 17:36.

Do tej pory wprowadziłem następujące zmiany, aby upewnić się, że wąskim gardłem nie jest TCP / IP. Dodano do /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

Więcej informacji o debugowaniu:

[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 worker_rlimit_nofileUstawiono na 10240konfigurację nginx.

AKTUALIZACJA 2011 12 09 GMT 19:02.

Wygląda na to, że im więcej zmian dokonam, tym gorzej, ale tutaj nowy plik konfiguracyjny.

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;
}

AKTUALIZACJA 2011 12 11 GMT 20:11.

Jest to generowane netstat -ntlapodczas testu.

https://gist.github.com/d74750cceba4d08668ea

AKTUALIZACJA 2011 12 12 GMT 10:54.

Aby wyjaśnić, iptables(zapora ogniowa) jest wyłączona podczas testowania.

AKTUALIZACJA 2011 12 12 GMT 22:47.

To jest sysctl -p | grep memzrzut.

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

AKTUALIZACJA 2011 12 12 GMT 22:49

Używam blitz.iodo uruchomienia wszystkich testów. Adres URL, który testuję, to http://dev. stycznia.com/test.txt, przy użyciu następującego polecenia:--region ireland --pattern 200-250:30 -T 1000 http://dev.anuary.com/test.txt

AKTUALIZACJA 2011 12 13 GMT 13:33

nginxlimity użytkownika (ustawione w /etc/security/limits.conf).

nginx       hard nofile 40000
nginx       soft nofile 40000
Guy
źródło
Hostujesz to sam? Brak równoważenia obciążenia lub coś takiego przed serwerem? Coś od ISP, który może wykryć to jako atak DDoS i spowolnić?
Bart Silverstrim,
Tak, to mój serwer. ovh.co.uk/dedicated_servers/eg_ssd.xml Nic, co by spowolniło atak DDoS. Ja też wzrosłem worker_processesdo 4.
Gajus,
Właśnie skontaktowałem się z OVH, aby dokładnie sprawdzić, czy na moim serwerze nie ma żadnych zabezpieczeń na poziomie sieci. Nie, nie ma.
Gajus,
jakie dane z tego podajesz? HTML, obrazy itp.?
pablo
1
Myślę, że pomogłoby to uruchomić lokalny test porównawczy, aby wykluczyć konfigurację nginx. Nie ty
3molo,

Odpowiedzi:

2

Podczas testu będziesz musiał zrzucić połączenia sieciowe. Podczas gdy serwer może mieć prawie zerowe obciążenie, stos TCP / IP może być obciążany. Poszukaj połączeń TIME_WAIT w danych wyjściowych netstat.

W takim przypadku warto sprawdzić, jak dostrajać parametry jądra tcp / ip związane ze stanami TCP Wait, recyklingiem TCP i podobnymi parametrami.

Nie opisałeś również tego, co jest testowane.

Zawsze testuję:

  • zawartość statyczna (obraz lub plik tekstowy)
  • prosta strona php (na przykład phpinfo)
  • strona aplikacji

Może to nie dotyczyć twojego przypadku, ale robię to podczas testowania wydajności. Testowanie różnych typów plików może pomóc w określeniu wąskiego gardła.

Nawet w przypadku treści statycznych ważne jest również testowanie różnych rozmiarów plików, aby uzyskać limity czasu i inne parametry.

Mamy kilka statycznych skrzynek Nginx obsługujących ponad 3000 aktywnych połączeń. Tak więc Nginx z pewnością może to zrobić.

Aktualizacja: Twój netstat pokazuje wiele otwartych połączeń. Może chcesz dostrajać swój stos TCP / IP. Ponadto o jaki plik prosisz? Nginx powinien szybko zamknąć port.

Oto sugestia dla 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

Wartości te są bardzo niskie, ale udało mi się z nimi odnieść do urządzeń Nginx o wysokiej współbieżności.

jeffatrackaid
źródło
ZobaczUPDATE 2011 12 09 GMT 17:36.
Gajus
dodano zaktualizowane do głównej odpowiedzi z powodu kodu.
jeffatrackaid
dodaj pełny górny wynik podczas testu, nie powinieneś sprawdzać tylko ile procesora używa nginx.
Giovanni Toraldo
1
bądź ostrożny, używając net.ipv4.tcp_tw_recycle = 1, ogólnie mówiąc: niezbyt dobry pomysł. ponowne użycie jest w porządku.
anonimowy -
Dlaczego nie użyć gniazda Linux zamiast localhost?
BigSack,
1

Kolejna hipoteza. Zwiększyłeś worker_rlimit_nofile, ale maksymalna liczba klientów jest zdefiniowana w dokumentacji jako

max_clients = worker_processes * worker_connections

Co jeśli spróbujesz podbić worker_connectionsdo 8192? Lub, jeśli jest wystarczająca liczba rdzeni procesora, zwiększ worker_processes?

minaev
źródło
1

Miałem bardzo podobny problem z modułem nginx służącym jako moduł równoważenia obciążenia z serwerami apache powyżej.

W moim przypadku udało mi się wyodrębnić problem związany z siecią, ponieważ serwery apache upstream zostały przeciążone. Mogłem go odtworzyć za pomocą prostych skryptów bash, gdy cały system był obciążony. Zgodnie z ciągiem jednego z zawieszonych procesów połączenie typu Connect otrzymywało ETIMEDOUT.

Te ustawienia (na serwerach nginx i upstream) wyeliminowały dla mnie problem. Dostawałem 1 lub 2 limity czasu na minutę przed wprowadzeniem tych zmian (skrzynki obsługujące ~ 100 reqs / s), a teraz dostaję 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

Nie polecałbym używania net.ipv4.tcp_tw_recycle lub net.ipv4.tcp_tw_reuse, ale jeśli chcesz użyć jednego, użyj drugiego. Mogą powodować dziwne problemy, jeśli występują jakiekolwiek opóźnienia, a te ostatnie są co najmniej bezpieczniejsze z obu.

Myślę, że ustawienie tcp_fin_timeout na 1 powyżej może również powodować problemy. Spróbuj ustawić go na 20/30 - wciąż znacznie poniżej wartości domyślnej.

gtuhl
źródło
0

może nie jest to problem z Nginx, podczas testowania na Blitz.io wykonaj:

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

(właśnie tego używam do obsługi php)

powoduje to błąd i limity czasu zaczynają rosnąć:

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

więc umieść więcej max_children na fmp conf i gotowe! ;RE

jipipayo
źródło
Problem jest taki sam, jeśli mam return 200 "test"w NGINX. Oznacza to, że NGINX nie posuwa się nawet tak daleko, aby wywoływać PHP-FPM.
Gajus
0

Masz za mało max open files(1024), spróbuj zmienić i zrestartuj nginx. (w cat /proc/<nginx>/limitscelu potwierdzenia)

ulimit -n 10240

I zwiększ worker_connectionsdo 10240 lub wyższej.

3368344
źródło
Nie jestem pewien, dlaczego zostało to przegłosowane. Brzmi dla mnie jak odpowiednia odpowiedź.
Ryan Angilly