Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Ajax vs sockety, zużycie CPU
Forum PHP.pl > Inne > Hydepark
nmts
Mam stronę, która w krótkim czasie jest odwiedzana przez 2500 osób, dla każdej z tych osób odpala się ajax co 5 sekund (celem aktualizacji wyświetlanych danych),
co sprawia, że zużycie 4 rdzeni na VPS jest na dość wysokim poziomie. Chciałbym zmniejszyć zużycie CPU przez zastosowanie zamiast ajaxa socket.io po stronie front-endu oraz nodejs po stronie back-endu,
po środku by był elephant.io - schemat działania byłby następujący: użytkownik po przez php (elephant.io) wysyłał by wiadomość do serwera (nodejs), a ten z kolei rozsyłał by wiadomość ze zmianą do wszystkich połączych przez sockety.

Czy jest ktoś mi w stanie powiedzieć jaki jestem w stanie uzyskać skok w wydajności stosując takie rozwiązanie zamiast ajaxa? (procentowo, liczbowo, whatever)
by_ikar
Jeżeli nie będziesz wysyłać za dużo emitów na sekundę, bo przecież możesz robić broadcast do wszystkich klientów, co jest w sumie jednym emitem. kwestia tego ile tych emitów będziesz robić od klientów; to widziałem gdzieś konfiguracje jak upchnąć milion aktywnych połączeń na 16gb ram. Nie bardzo rozumiem po co ci elephant.io, skoro dostęp do soketów masz już po stronie frontendu..

I tak, sokety będą wydajniejsze od xhr'a, który będzie za każdym razem tworzyć nowe połączenie, zupełnie inaczej niż sokety, które będą to połączenie utrzymywać.
nmts
Cytat(by_ikar @ 7.04.2015, 08:39:51 ) *
Jeżeli nie będziesz wysyłać za dużo emitów na sekundę, bo przecież możesz robić broadcast do wszystkich klientów, co jest w sumie jednym emitem. kwestia tego ile tych emitów będziesz robić od klientów; to widziałem gdzieś konfiguracje jak upchnąć milion aktywnych połączeń na 16gb ram. Nie bardzo rozumiem po co ci elephant.io, skoro dostęp do soketów masz już po stronie frontendu..

I tak, sokety będą wydajniejsze od xhr'a, który będzie za każdym razem tworzyć nowe połączenie, zupełnie inaczej niż sokety, które będą to połączenie utrzymywać.


No właśnie broadcast do wszystkich byłby najsensowniejszy. Emitów będzie tyle ile osób, które odwiedza stronę czyli np. 2500 jak w przykładzie, bo każda wchodząc może zmienić jednorazowo dane.
Elephant.io chciałem użyć ponieważ wtedy całość ogranicza się jedynie do wysłania emita do serwera w odpowiednim momencie, gdybym robił to po stronie front-endu to musiałbym rozbudować
kod po stronie nodejs celem walidacji danych i uzupełniania danych w bazie - a ponieważ nie znam się na nodejs dlatego chciałem to maksymalnie uprościć.
Na razie nie mam do tego głowy, dałem ogłoszenie na freelancerach, może ktoś mi to ogarnie. closedeyes.gif
by_ikar
No to może zamiast sokety, użyj server sent events, z xhr'em dla przeglądarek które tego nie obsługują (ie). I całość możesz zrobić w php z odrobiną javascriptu. Nie rozumiem, emitów tyle co osób? Po co ci tyle emitów jednocześnie ?
nmts
Cytat
Nie rozumiem, emitów tyle co osób? Po co ci tyle emitów jednocześnie ?


Nie jednocześnie, w krótkim odstępie czasu. Jest to strona do tworzenia ankiet online, wyniki ankiet są aktualizowane na bieżąco - aktualnie za pomocą ajaxa. To tak pokrótce opisując przypadek.

Cytat
No to może zamiast sokety, użyj server sent events


Nie podoba mi się w SSE, że żeby to w ogóle działało muszę przesłać określoną ilość znaków (chociażby białych) z uwagi na limity przeglądarek (wiadomości tą metodą zostaną odebrane gdy zostanie przekroczona określona ilość bajtów). Może się nie potrzebnie czepiam, ale mnie to denerwuje, bo to znacznie więcej niż potrzebuje przesłać. snitch.gif No chyba, że jest jakieś rozwiązanie, o którym nie wiem. Nie mówiąc już o tym, że zawsze by było coś wysyłane nawet jakby nic się nie zmieniło, no chyba, że po prostu nie wiem jakby to miało działać. wink.gif
by_ikar
Sokety też wysyłają handshak'i, które też zawierają jakieś znaki, nie ma tego tam za dużo, no ale też jest. Zaproponowałem ci SSE z uwagi na to że jak to napisałeś, nie chcesz babrać się w js, bo wolisz to zrobić w php. A roboty jest tak na prawdę tyle samo. A JS tak na prawdę źle wygląda tylko po stronie przeglądarki z uwagi na DOM, tam gdzie tego DOM'a nie ma, JS jest nawet przyjemny.

Podsumowując, 4 rdzenia nie wiele mi mówią, fajnie by było wiedzieć jakie to są 4 rdzenia. Kolejna sprawa jest taka że node jest 1 wątkowy, czyli będzie pracować i tak na jednym rdzeniu. Do tego musisz albo napisać sobie klaster, albo użyć jakiegoś pakietu który ten klaster uruchomi z drobną konfiguracją. Dodatkowo potrzebujesz jakiś spawner, bo node sam w sobie może ci się wywalić, w końcu jest to wersja aż 0.10, więc jest to zrozumiałe i tutaj też przyda się jakiś spawner. Również polecam PM2 bo on dokładnie to robi, dzięki czemu aplikacja działa bez przerwy. No a jak klaster, a node chodzi w jednym wątku, to musisz jakoś połączyć sokety, aby nie było tak że użytkownicy będą w różnych wątkach i się ze sobą nie dogadają, więc przyda ci się jakiś redis, czy inny, aby te emity współdzielić. Jest z tym sporo roboty, sporo do nauczenia się. Stąd moja propozycja odnośnie SSE. Ale jeżeli to ogarniesz i nie są to jakieś beznadziejne rdzenia, to spokojnie powinieneś dać rade, w sumie nawet w jednym wątku, kwestia tego jaki to jest procesor.
!*!
Cytat(nmts @ 7.04.2015, 02:06:48 ) *
... jest odwiedzana przez 2500 osób ... Jest to strona do tworzenia ankiet online, wyniki ankiet są aktualizowane na bieżąco ...


2500? 2,5k? dwa tysiące pięćset? Toć to maleństwo. Panie, weź Pan pierwszy lepszy z brzegu serwer ws w php (python) pisany na kolanie, zrób obsługę websocetów po stronie przeglądarki (flash dla kompatybilności z ie) mała obróbka JSON i po sprawie... a nie wyciągasz rakiety atomowe na komara :D
nmts
Cytat
2500? 2,5k? dwa tysiące pięćset? Toć to maleństwo. Panie, weź Pan pierwszy lepszy z brzegu serwer ws w php (python) pisany na kolanie, zrób obsługę websocetów po stronie przeglądarki (flash dla kompatybilności z ie) mała obróbka JSON i po sprawie... a nie wyciągasz rakiety atomowe na komara biggrin.gif


Aktualnie ilość jednoczesnych userów może dosiegać tej liczby, ale mój plan rozwoju (który czeka na wdrożenie) przewiduje większe liczby (dokładnie nie wiem). Są to krótkotrwałe odwiedziny, ale stosując obecne rozwiązania bardzo zasobożerne. tongue.gif Nie mniej pomyśle nad serwerem w php, może na chwilę obecną wystarczy. snitch.gif
Tuminure
Cytat
Nie jednocześnie, w krótkim odstępie czasu. Jest to strona do tworzenia ankiet online, wyniki ankiet są aktualizowane na bieżąco - aktualnie za pomocą ajaxa. To tak pokrótce opisując przypadek.

Ale przecież ilość emitów nie powinna być zależna od ilości użytkowników, a po prostu powinny być wysyłane broadcasty zależne od ilości ankiet.

1 broadcast = 1 ankieta.
Jeżeli dajmy na to masz 10 aktywnych ankiet, to wysyłasz co 5 sekund 10 broadcastów, które trafiają do wszystkich oglądających poszczególne ankiety.

Ewentualnie...
1 broadcast = wszystkie ankiety.
Możesz rozsyłać nawet i jeden broadcast do każdego użytkownika strony, który będzie zawierał dane z wszystkich ankiet. Jeżeli masz zamiar mieć dużo aktywnych ankiet, to może być przesyłane zbyt dużo danych... jeżeli jednak masz kilka ankiet, to nie rozdrabniałbym się i po prostu zrobił to w taki sposób.
nmts
Cytat
Ale przecież ilość emitów nie powinna być zależna od ilości użytkowników, a po prostu powinny być wysyłane broadcasty zależne od ilości ankiet.


Tu chodziło mi o emity z PHP przesyłane do serwera ws informujące go o oddaniu głosu. No bo przecież zanim serwer wyślę broadcast do użytkowników konkretnej ankiety, to musi on sam zostać powiadomiony, że został oddany głos w ankiecie prawda? Schemat, który planowałem osiągnąć wygląda tak: [PHP] -> emit -> [WS] -> broadcast -> [Front-end]
Co prawda aktualnie ankiety się odświeżają co 5 sekund, ale chciałem jednocześnie osiągnąć efekt natychmiastowej aktualizacji po każdym oddaniu głosu.

Jakby kogoś interesowało to zrobiłem to przy użyciu: Ratchet + ZeroMQ + Autobahn
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.