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

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.


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?


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.


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


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.


Nie jestem pewien, dlaczego zostało to przegłosowane. Brzmi dla mnie jak odpowiednia odpowiedź.
Ryan Angilly
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.