Jak sugeruje tytuł pytania, mam trudności z ustaleniem, co można ulepszyć w mojej aplikacji (lub dostroić w OS, Ubuntu), aby osiągnąć akceptowalną wydajność. Ale najpierw wyjaśnię architekturę:
Serwer front-end to 8-rdzeniowa maszyna z 8 gigabajtami pamięci RAM i systemem Ubuntu 12.04. Aplikacja jest napisana w całości w javascript i uruchomiona w node.js v 0.8.22 (ponieważ niektóre moduły wydają się narzekać na nowsze wersje węzła) używam nginx 1.4 do proxy ruchu HTTP z portu 80 i 443 do 8 pracowników węzłów, które są zarządzane i zaczął używać interfejsu API klastra węzłów. Używam najnowszej wersji socket.io 0.9.14 do obsługi połączeń websocket, na których włączyłem tylko websockets i xhr-polling jako dostępne transporty. Na tym komputerze uruchamiam również instancję Redis (2.2)
Przechowuję trwałe dane (takie jak użytkownicy i wyniki) na drugim serwerze na mongodb (3.6) z 4 GB pamięci RAM i 2 rdzeniami.
Aplikacja jest produkowana od kilku miesięcy (kilka tygodni temu działała na jednym pudełku) i jest używana przez około 18 000 użytkowników dziennie. Zawsze działało bardzo dobrze, pomijając jeden główny problem: spadek wydajności. Wraz z użyciem ilość procesora wykorzystywana przez każdy proces rośnie, dopóki nie osiągnie dojrzałości pracownika (który nie będzie już obsługiwał żądań). Tymczasowo rozwiązałem to sprawdzanie procesora używanego przez każdego pracownika co minutę i uruchamianie go ponownie, jeśli osiągnie 98%. Problemem jest więc głównie procesor, a nie pamięć RAM. Pamięć RAM nie jest już problemem, ponieważ zaktualizowałem do socket.io 0.9.14 (wcześniejsza wersja przeciekała pamięć), więc wątpię, aby była to kwestia nieszczelności pamięci, zwłaszcza że teraz jest to procesor, który rośnie dość szybko ( Każdego pracownika muszę ponownie uruchamiać około 10-12 razy dziennie!). Używana pamięć RAM również rośnie, mówiąc szczerze, ale bardzo powoli, 1 koncert co 2-3 dni użytkowania, a dziwne jest to, że nie jest on uwalniany nawet po całkowitym zrestartowaniu całej aplikacji. Zostanie wydany tylko po ponownym uruchomieniu serwera! tego tak naprawdę nie rozumiem ...
Teraz odkryłem, że Nodefly jest niesamowity, więc w końcu mogę zobaczyć, co się dzieje na moim serwerze produkcyjnym, i zbieram dane od kilku dni. Jeśli ktoś chce zobaczyć wykresy, mogę dać ci dostęp, ale w zasadzie widzę, że mam od 80 do 200 jednoczesnych połączeń! Spodziewałem się, że node.js obsłuży tysiące, a nie setki żądań. Również średni czas odpowiedzi dla ruchu http waha się między 500 a 1500 milisekund, co moim zdaniem to naprawdę dużo. Również w tym momencie, gdy 1300 użytkowników jest online, jest to wynik działania „ss -s”:
Total: 5013 (kernel 5533)
TCP: 8047 (estab 4788, closed 3097, orphaned 139, synrecv 0, timewait 3097/0), ports 0
Transport Total IP IPv6
* 5533 - -
RAW 0 0 0
UDP 0 0 0
TCP 4950 4948 2
INET 4950 4948 2
FRAG 0 0 0
co pokazuje, że mam dużo zamkniętych połączeń w oczekiwaniu na czas. Zwiększyłem maksymalną liczbę otwartych plików do 999999, oto wynik działania 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) 63724
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 999999
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 63724
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
Pomyślałem więc, że problem może dotyczyć ruchu HTTP, który z jakichś powodów nasyca dostępne porty / gniazda (?), Ale jedna rzecz nie ma dla mnie sensu: dlaczego po ponownym uruchomieniu pracowników i wszyscy klienci łączą się ponownie w ciągu kilku sekund, obciążenie procesora spada do 1% i jest w stanie poprawnie obsługiwać żądania, dopóki nie nasyci się po około 1 godzinie (w szczycie)?
Jestem głównie programistą javascript, a nie administratorem systemu, więc nie wiem, ile obciążenia powinienem oczekiwać na moich serwerach, ale na pewno nie działa tak, jak powinien. W przeciwnym razie aplikacja jest stabilna, a ten ostatni problem uniemożliwia mi wysyłanie gotowych wersji aplikacji mobilnych, ponieważ oczywiście przyniosą więcej obciążenia i ostatecznie spowodują awarię!
Mam nadzieję, że jest coś oczywistego, że robię źle, i ktoś pomoże to zauważyć ... nie wahaj się poprosić mnie o więcej informacji i przepraszam za długość pytania, ale było konieczne Wierzę ... z góry dziękuję!
top
gdy użycie procesora jest bliskie 100%?