Dlaczego mój serwer internetowy przerywa połączenia przy resecie TCP przy dużym obciążeniu?

10

Mam małą konfigurację VPS z nginx. Chcę wycisnąć z niego jak najwięcej wydajności, więc eksperymentowałem z optymalizacją i testowaniem obciążenia.

Używam Blitz.io do testowania obciążenia POBIERZ mały statyczny plik tekstowy i napotykam dziwny problem, w którym serwer wydaje się wysyłać resety TCP, gdy liczba jednoczesnych połączeń osiągnie około 2000. Wiem, że to bardzo duża ilość, ale dzięki użyciu htop serwer wciąż ma dużo do stracenia czasu procesora i pamięci, więc chciałbym dowiedzieć się, skąd ten problem, czy mogę go jeszcze bardziej rozwinąć.

Używam Ubuntu 14.04 LTS (64-bit) na 2GB Linode VPS.

Nie mam wystarczającej reputacji, aby opublikować ten wykres bezpośrednio, więc oto link do wykresu Blitz.io:

wprowadź opis zdjęcia tutaj

Oto rzeczy, które zrobiłem, aby znaleźć źródło problemu:

  • Wartość konfiguracyjna nginx worker_rlimit_nofilejest ustawiona na 8192
  • zostały nofileustawione na 64000 zarówno twardych i miękkich limitów rooti www-dataużytkownik (co działa jak nginx) w/etc/security/limits.conf
  • nic nie wskazuje na to, że coś idzie nie tak /var/log/nginx.d/error.log(zazwyczaj, jeśli napotykasz limity deskryptorów plików, nginx wyświetli komunikat o błędzie)

  • Mam konfigurację ufw, ale nie ma reguł ograniczających szybkość. Dziennik ufw wskazuje, że nic nie jest blokowane i próbowałem wyłączyć ufw z tym samym skutkiem.

  • Nie ma żadnych orientacyjnych błędów w /var/log/kern.log
  • Nie ma żadnych orientacyjnych błędów w /var/log/syslog
  • Dodałem następujące wartości /etc/sysctl.confi załadowałem je sysctl -pbez efektu:

    net.ipv4.tcp_max_syn_backlog = 1024
    net.core.somaxconn = 1024
    net.core.netdev_max_backlog = 2000
    

Jakieś pomysły?

EDYCJA: Zrobiłem nowy test, zwiększając do 3000 połączeń na bardzo małym pliku (tylko 3 bajty). Oto wykres Blitz.io:

Wykres Blitz.io

Ponownie, według Blitz, wszystkie te błędy są błędami „resetowania połączenia TCP”.

Oto wykres przepustowości Linode. Pamiętaj, że jest to średnia 5-minutowa, więc jest nieco przefiltrowana przez filtr dolnoprzepustowy (chwilowa przepustowość jest prawdopodobnie znacznie wyższa), ale to nic:

wprowadź opis zdjęcia tutaj

PROCESOR:

wprowadź opis zdjęcia tutaj

I / O:

wprowadź opis zdjęcia tutaj

Oto htopkoniec testu: htop

Przechwyciłem także część ruchu za pomocą tcpdump w innym (ale podobnie wyglądającym) teście, rozpoczynając przechwytywanie, gdy zaczęły pojawiać się błędy: sudo tcpdump -nSi eth0 -w /tmp/loadtest.pcap -s0 port 80

Oto plik, jeśli ktoś chce go obejrzeć (~ 20 MB): https://drive.google.com/file/d/0B1NXWZBKQN6ETmg2SEFOZUsxV28/view?usp=sharing

Oto wykres przepustowości z Wireshark:

wprowadź opis zdjęcia tutaj (Linia to wszystkie pakiety, niebieskie paski to błędy TCP)

Z mojej interpretacji przechwytywania (i nie jestem ekspertem), wygląda na to, że flagi TCP RST pochodzą ze źródła testowania obciążenia, a nie z serwera. Zakładając, że po stronie usługi testowania obciążenia coś jest nie tak, czy można bezpiecznie założyć, że jest to wynikiem pewnego rodzaju zarządzania siecią lub łagodzenia DDOS między usługą testowania obciążenia a moim serwerem?

Dzięki!

Erik Swan
źródło
Czy Twój dostawca dokonuje pewnego rodzaju łagodzenia DDoS? Może to zakłócać twój test.
Michael Hampton
@MichaelHampton Jestem całkiem pewien, że Linode tego nie robi.
EEAA
Czy możesz opublikować wykres sieci z panelu sterowania Linode? Ile przepustowości faktycznie zajmuje ten test?
EEAA
Zrobiłem trochę więcej dochodzeń i zaktualizowałem oryginalny post o wiele więcej informacji. Potwierdziłem również z Linode, że nie ograniczają DDOS, chociaż niekoniecznie oznacza to, że dostawca sieci między usługą testowania obciążenia a Linode nic nie robi. Dzięki!
Erik Swan
1
Czy istnieje powód, dla którego ustawiłeś tylko net.core.netdev_max_backlog2000? W kilku przykładach widziałem, że jest to rząd wielkości wyższy dla połączeń gigabitowych (i 10Gig).
Moshe Katz,

Odpowiedzi:

1

Może istnieć dowolna liczba źródeł resetowania połączenia. Tester obciążenia może być niedostępny z efemerycznych portów, z których można nawiązać połączenie, urządzenie po drodze (takie jak zapora sieciowa wykonująca NAT) może mieć wyczerpaną pulę NAT i nie może zapewnić portu źródłowego dla połączenia, czy istnieje moduł równoważenia obciążenia lub zapora ogniowa na twoim końcu, który mógł osiągnąć limit połączeń? A jeśli robisz źródłowy NAT dla ruchu przychodzącego, może to również powodować wyczerpanie portów.

Naprawdę potrzebny byłby plik pcap z obu końców. To, czego chcesz szukać, to próba wysłania próby połączenia, ale nigdy nie dociera do serwera, ale nadal wygląda na zresetowaną przez serwer. W takim przypadku coś po linii musiało zresetować połączenie. Wyczerpanie puli NAT jest częstym źródłem tego rodzaju problemów.

Ponadto netstat -st może dać ci dodatkowe informacje.

GeorgeB
źródło
1

Kilka pomysłów do wypróbowania w oparciu o moje ostatnie podobne doświadczenia tuningowe. Z referencjami:

Mówisz, że to statyczny plik tekstowy. Na wypadek, gdyby miało miejsce jakiekolwiek przetwarzanie w górę, najwyraźniej gniazda domeny poprawiają przepustowość TCP przez połączenie oparte na porcie TC:

https://rtcamp.com/tutorials/php/fpm-sysctl-tweaking/ https://engineering.gosquared.com/optimising-nginx-node-js-and-networking-for-heavy-workloads

Niezależnie od wcześniejszego zakończenia:

Włącz multi_accept i tcp_nodelay: http://tweaked.io/guide/nginx/

Wyłącz TCP Slow Start: /programming/17015611/disable-tcp-slow-start http://www.cdnplanet.com/blog/tune-tcp-initcwnd-for-optimum-performance/

Optymalizuj okno przeciążenia TCP (initcwnd): http://www.nateware.com/linux-network-tuning-for-2013.html

JayMcTee
źródło
1

Aby ustawić maksymalną liczbę otwartych plików (jeśli to powoduje problem), musisz dodać „fs.file-max = 64000” do /etc/sysctl.conf

Sean1e
źródło
0

Proszę sprawdzić, ile portów jest w TIME_WAITstanie za pomocą polecenia netstat -patunl| grep TIME | wc -li zmienić net.ipv4.tcp_tw_reusena 1.

fgbreel
źródło
Jak spojrzałbym na ile portów jest w TIME_WAITstanie?
Erik Swan,
Za pomocą netstatlub ss. Zaktualizowałem swoją odpowiedź kompletnym poleceniem!
fgbreel
Ponownie uruchomiłem test i watch -n 1 'sudo netstat -patunl | grep TIME | wc -l'zwracam 0 podczas całego testu. Jestem pewien, że resety nadchodzą w wyniku ograniczenia DDOS przez kogoś między testerem obciążenia a moim serwerem, na podstawie mojej analizy pliku PCAP, który zamieściłem powyżej, ale jeśli ktoś mógłby potwierdzić, byłoby świetnie!
Erik Swan,