Pracuję nad dość nietypową aplikacją, w której klienci 10k są dokładnie taktowani, aby wszyscy próbowali przesłać dane naraz, co 3 minuty. Ta komenda „ab” dość dokładnie symuluje jedną zaporę w świecie rzeczywistym:Node.js boryka się z wieloma równoczesnymi połączeniami
ab -c 10000 -n 10000 -r "http://example.com/submit?data=foo"
używam node.js na Ubuntu 12.4 na rackspacecloud VPS wystąpienie do zbierania tych wniosków, jednak widzę niektóre bardzo dziwne zachowanie z węzła, nawet po usunięciu całej logiki biznesowej i przekształceniu żądania http w operację "no-op".
Po wykonaniu około 90% testu zawiesza się na długi czas. Co dziwne, dzieje się to konsekwentnie na poziomie 90% - dla c = n = 10 000, przy 9000; dla c = n = 5k, przy 4500; dla c = n = 2k, przy 1800. Test faktycznie się kończy, często bez błędów. Ale zarówno rejestry ab, jak i węzłowe wykazują ciągłe przetwarzanie do około 80-90% przebiegu testu, następnie długą przerwę przed zakończeniem.
Gdy węzeł przetwarza żądania w normalny sposób, użycie procesora zwykle wynosi około 50-70%. Podczas okresu oczekiwania CPU osiąga nawet 100%. Czasami pozostaje blisko 0. Pomiędzy błędną reakcją CPU i faktem, że wydaje się ona niezwiązana z faktyczną liczbą połączeń (tylko% complete), nie podejrzewam, że jest to zbieracz.
Próbowałem tego działającego "ab" na localhost i na zdalnym serwerze - ten sam efekt.
Podejrzewam, że coś jest związane ze stosem TCP, prawdopodobnie z zamykaniem połączeń, ale żadna z moich zmian konfiguracji nie pomogła. Moje zmiany:
- ulimit -n 999999
- Kiedy słucham(), ustawić zaległości 10000
zmiany sysctl są:
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.tcp_max_orphans = 20000
net.ipv4.tcp_max_syn_backlog = 10000
net.core.somaxconn = 10000
net.core.netdev_max_backlog = 10000
Mam również zauważyć, że Mam tendencję do uzyskania tego komunikatu msg w dziennikach jądra:
TCP: Possible SYN flooding on port 80. Sending cookies. Check SNMP counters.
Jestem zaskoczony tym komunikatem, ponieważ kolejka protokołów TCP powinna być na tyle głęboka, aby nigdy nie przepełniać. Jeśli wyłączyłem pliki cookie synów, "Wysyłanie plików cookie" przechodzi do "Zrzutu połączeń".
Spekuluję, że jest to jakikolwiek problem z tuningowaniem stosów TCP w systemie Linux i przeczytałem prawie wszystko, co mogłem znaleźć w sieci. Nic, co próbowałem, wydaje się nie mieć znaczenia. Jakakolwiek rada?
Aktualizacja: Próbowałem z tcp_max_syn_backlog, somaxconn, netdev_max_backlog i słuchać() zaległości param zestaw do 50k bez zmiany zachowań. Wciąż generuje również ostrzeżenie o powodzi SYN.
Na marginesie jestem bardzo zainteresowany w końcowym roztworze do tego jak muszę nodejs z dużą liczbą aktywnych połączeń również. –
Dla tego, co jest warte, tak wydajne, jak może być Node, połączenia 10k wszystkie robienie czegoś na raz jest większym obciążeniem niż pozostawiłbym jednemu VPS. – Brad