Czy WebSocket będzie dobry do setek tysiecy klientów?

0

Potrzebuje napisać aplikację która będzie serwować dane do połączonych klientów. Klientów będzie setki tysięcy jak nie miliony.

  1. Co w takim przypadku będzie wydajniejsze WebSocket, ServerSocket czy coś innego?
  2. Do napisania serwera wykorzystać lepiej java EE z serwerem aplikacyjnych czy zwykła java?

Aplikacja klienta będzie na telefon jak i wersja przeglądarkowa.

1

Nie miałem takiego problemu więc mogę czegoś nie wiedzieć . Tylko nie wiem czy dużo ludzi miało... więc postaram się pomóc z tego co wiem.

Akurat znam się na Java EE i absolutnie nie polecam do tego. JavaEE i WS nijak nie pasują. Działa, ale w tej skali do niczego się Ci Java EE nie przyda. (Będziesz w Oraclu z 2PC dane od klientow zapisywał? ... powodzenia).

Twój problem przede wszystkim to bedzie infrastruktura sieci (rozproszenie i ograniczenia systemów operacyjnych ) - kod servera to drugorzedny problem.
Bedziesz musiał rozproszyc to na wiele ( > 10 ) serwerów - (czyli cloud)

Z czegoć co wiadomo, że uciągnie to Netty.
https://dzone.com/articles/512000-concurrent-websockets
Ratpack, który lubie jest na Netty i obługuje WS - ale to tylko biblioteka w Javie.

Jak to rozproszyć? Ostanio bawiłem się Lagom frameworkiem i tam rozproszenie i cloud to podstawa.
Ma wsparcie dla WS jako jedną z podstawowych rzeczy.
Działa domyślnie na Cassandrze (czyli NoSQL zrobiony głównie z myślą o rozpraszaniu).
Ale, że zrobiłem w tym tylko głupią gierke, i jeszcze nie przetestowałem wydajnośći to nie moge w żaden sposób ręczyć.

A tak poza tym, żeby zrobić tu w miarę prawdopodobny sizing i zaproponować architekturę to trzeba by było długo posiedzieć. BARDZO dużo zależy od tego co ten system ma robić, jak wiele i jak często informacji ma przesyłać. Jakie wymagania na czasy odpowiedzi, consistency (zapomnij :-) ), rozmiar danych roboczych itp.

0

A mozesz uzasadnic do czego maja posluzyc websockety? Stream feed? Real time updates?

Na ile skomplikowany bedzie ten backend?
Bo jesli nie jakas super zaawansowana logika biznesowa to jezyk Go moglby byc niezla opcja. Ma dobry throughput, fajna wspolbieznosc i jest wydajny.

1

WebSocket ma sens jak potrzebujesz dwukierunkowej komunikacji (full-dupleksowe) połączenie. Czy na pewno tego potrzebujesz? Typowe chaty są dobrym przykładem. Jak wystarczy Ci half-duplex to może event source (SSE) będzie ok. Taki half-duplex to na przykład aktualizacja live mapy z aktualnym miejscem, gdzie znajduje się samolot w locie.

1

Dokładnie websocket i pochodne są najczęściej używane do chatów, komunikatorów wszelkiej maści, czy systemów aukcyjnych/giełdowych.

1

No więc od dłuższego czasu w niektórych swoich "experymentalnych" aplikacjach stosuję tylko WS - bo to o wiele dla mnie wygodniejszy model. NIe ma RESTa-/ Jsona - nie żyją. To działa nieźle gdy na froncie wtedy stosuje taką swoją chorą mutację patternu SAM i React.a .
Jakkolwiek cały czas mam w głowie, że gdybym kiedyś miał coś takiego stosować dla tysięcy klientów - to być może trzeba będzie zrobić fallback na JSONowy polling eventów.

1

Często WebSocket służą jako tunelowanie messagingu wiadomości w formacie tekstowym. Służy do tego bardzo prosty protokół STOMP:
https://stomp.github.io/

Jest to taki asynchroniczny messaging na wyższym poziomie niż czysty WebSocket. Ale nie miałem okazji wykorzystać. Obsługuje kolejki, publush-subscribe i prymitywne transakcje (czy udało się dostarczyć komunikat po WebSocket).

Obsługuje klasyczne paradygmaty jak point-to-point oraz publish subscribe.

0

Dzięki za odzew :) Głównie chodzi o przesyłanie danych od użytkownika na serwer i z serwera do użytkownika kiedy pojawią nowe dane które powinny trafić do niego (średnio przesył danych na jednego użytkownika będzie co 5sekund lub częściej) x kilkaset tysięcy lub miliony użytkowników.
Sposób request-response średnio wchodzi w grę (konieczność trzymania obecnie pobranych danych i wysyłania tylko nowych na bieżąco).
Na pierwszy rzut oka najlepszym wyjściem jest WebSocket, bo w "dane" które już pobrał użytkownik będą trzymane w pamięci przez cały czas kiedy jest aktywne połączenie.
W przypadku request-response jest to też możliwe do zrobienia ale wymaga bardziej złożonej implementacji co wydaję się że spadnie wydajność serwera.
Aplikacje którą chcę napisać można porównać działaniem do czata ogólno-dostępnego dla wszystkich zalogowanych użytkowników.

Co do obsługi tak dużęj ilości klientów, czy nie lepiej napisać aplikacje tak aby mogłą działać klastrowo?
Wtedy nasuwa się pytanie jak to zrobić? Stworzyć serwer głowny który odbiera połączenia i deleguje je na serwery podrzędne?

1

Klastrowo -> Zobacz przykład chat/twittera w Lagom
https://github.com/lagom/activator-lagom-java-chirper
Obsługuje WS (nadal to tylko "pokazówka")

1
darksead napisał(a):

Wtedy nasuwa się pytanie jak to zrobić? Stworzyć serwer głowny który odbiera połączenia i deleguje je na serwery podrzędne?

Load balancer?

0

jesli chodzi o load balancing to chodzi o instalacje kilku serwerow pod jedna domena DNS i na poziomie proby polaczenia klienta do serwera bedzie kierowane polaczenie do najmniej obciazonego? Sa juz jakies gotowe rozwiazania tego typu czy samemu musialbym cos takiego napisac? Jesli samemu to jak sie za to zabrać?

1

Na poziomie DNS (to co mniej więcej opisujesz) - działa tzn round robin DNS - klient łączy się z losowym z dostępnych IP (ale nie z najmniej obciążonym, bo tego klient nie wie).

Możesz mieć load balancer na poziomie serwera "proxy"
od apache mod_proxy_load-balancer (dość prymitywny),
przez varnish HTTP cache
i w cholere dużo różnego komercyjnego - np. F5.

Takie proxy może inteligentnie przekierowywać ruch - najczęściej przede wszystkim dba po prostu o sprawdzanie które z nodów są aktywne (np. regularny ping) i kieruje połączenia tylko do działających.

Z algorytmow wybierania to generalnie najczęściej (chyba - statystyk nie mam) się używa round robin czyli losowego przydzielania. Bo różnego rodzaju algorytmy typu najmniej obciążony, najmniej połączeń są podatne na dziwne problemy. (Przykładowo serwer może mieć mało połączeń - bo nie wyrabia i je dropuje..., albo dopiero startuje i trzeba mu dać czas na rozgrzewkę ( a nie od razu zasypać ziemniakami )).

Load balancer jest też niezbędny jak chcesz uniknąć downtime - czyli np. wrzucasz nową wersje softu to po kolei odpinasz nody , na każdym robisz update i go przypinasz na powrót. W ten sposób nawet mając mnóstwo podpiętych klientów można zrobić update softu tak, że nikt się nie zorientuje.

1

W spring cloud masz ribbona, client side load balancer. Ogolnie mozesz poczytac co mozesz dostac od springa.

Sa tez rzeczy jak haproxy.

Poczytaj tez o api gateway.

0
jarekr000000 napisał(a):

Nie miałem takiego problemu więc mogę czegoś nie wiedzieć . Tylko nie wiem czy dużo ludzi miało... więc postaram się pomóc z tego co wiem.

Akurat znam się na Java EE i absolutnie nie polecam do tego. JavaEE i WS nijak nie pasują. Działa, ale w tej skali do niczego się Ci Java EE nie przyda. (Będziesz w Oraclu z 2PC dane od klientow zapisywał? ... powodzenia).

Twój problem przede wszystkim to bedzie infrastruktura sieci (rozproszenie i ograniczenia systemów operacyjnych ) - kod servera to drugorzedny problem.
Bedziesz musiał rozproszyc to na wiele ( > 10 ) serwerów - (czyli cloud)

Z czegoć co wiadomo, że uciągnie to Netty.
https://dzone.com/articles/512000-concurrent-websockets
Ratpack, który lubie jest na Netty i obługuje WS - ale to tylko biblioteka w Javie.

Jak to rozproszyć? Ostanio bawiłem się Lagom frameworkiem i tam rozproszenie i cloud to podstawa.
Ma wsparcie dla WS jako jedną z podstawowych rzeczy.
Działa domyślnie na Cassandrze (czyli NoSQL zrobiony głównie z myślą o rozpraszaniu).
Ale, że zrobiłem w tym tylko głupią gierke, i jeszcze nie przetestowałem wydajnośći to nie moge w żaden sposób ręczyć.

A tak poza tym, żeby zrobić tu w miarę prawdopodobny sizing i zaproponować architekturę to trzeba by było długo posiedzieć. BARDZO dużo zależy od tego co ten system ma robić, jak wiele i jak często informacji ma przesyłać. Jakie wymagania na czasy odpowiedzi, consistency (zapomnij :-) ), rozmiar danych roboczych itp.

Dlaczego WebSocketow nie implementować w JAVA EE? Przecież można to zrobić bardzo prosto przy pomocy adnotacji i opcja zarządzania wątkami też nam odpadnie bo zrobi to za nas kontener. Tak samo z transakcjami entity managera. Działą to wolniej niż napisanie tego przy użyciu zwykłej Javy?

1

Dlaczego WebSocketow nie implementować w JAVA EE? Przecież można to zrobić bardzo prosto przy pomocy adnotacji i opcja zarządzania wątkami też nam odpadnie bo zrobi to za nas kontener. Tak samo z transakcjami entity managera. Działą to wolniej niż napisanie tego przy użyciu zwykłej Javy?

Dokładnie wymieniłeś powody dlaczego nie robić tego na JavaEE. W pewnej skali transakcje (w znaczeniu JavaEE/SQL) to nie wolniej... to katastrofa.
Przy czym uwaga - uważam, że da się to zrobić w JavaEE (nie takie głupoty się robi) - tylko, że skorzystasz dokładnie z żadnych ficzerów JavaEE, bo np. raczej nie będziesz korzystał z SQL tylko weźmiesz bazę danych (jeśli jakąkolwiek) taką która wspiera AP z CAP - czyli np. Cassandra, CouchDB etc.

A najważniejsze - żeby to wszystko zrobić to trzeba się nauczyć JavaEE oraz oduczyć Javy -> nie warto.

0

Jeśli JAVA EE nie nadaje się do aplikacji z których mają korzystać miliony użytkowników to w jaki sposób działają aplikacje bankowe? Z tego co czytałem po ogłoszeniach o pracę to 99% bankowych ogłoszeń wymaga JAVE EE więc wynika że ich system także jest na tej technologii zbudowany, a korzystają z tego miliny ludzi. (Nie neguje tego co napisałeś tylko pytam z czystej ciekawości :) )

1

Według mnie używanie JavaEE jest mało praktyczne, lepsze rozwiązania open source niż enterprise na które trzeba czekać.
open source szybciej dostarcza rozwiązania na problemy, z którymi można się spotkać.

2

Jakby co pracuje w ubezpieczeniach, wcześniej robiłem kilka projektów w bankach. Rzeczywiście JavaEE (a zwłaszcza WAS) jest bardzo obecny. Faktycznie da się obsłużyć miliony klientów (pod warunkiem, że za dużo nie wymagają i logują się max raz na dwa dni :-) ). I ogólnie się wiele da.
Ale że pracuję z tym codziennie to generalnie nie polecam. Zresztą większym problemem jest nie JavaEE itself tylko ludzie. Po prostu do czasu aż wszyscy w zespole nie są specami JavaEE - to programowanie to spacer po polu minowym nieco tylko lepszy od JavaScriptu. Nawet nie wiesz ile ja pytań na review zadaje (ludzie piszą kod i nie wiedzą czemu działa, albo wrzucają adnotacje bo podpatrzyli u kolegi,( mu pomogło wiec też wrzucę - normalnie szamanizm)). Nawet nie mogę ogarnąć na ile pytań nie znam odpowiedzi (po nastu latach pisania w JavaEE -choć chyba dlatego, że zaczynam już więcej zapominać niż się uczyć). Eventualne odpowiedzi znajduje debugując websphera / bo ani stackoverflow ani doki ani specka nie jest jasna czasami- fajnie ). Czy muszę dodać, że największe kwiatki (czyste absurdy z punktu widzenia specyfikacji JavaEE) znajduje w kodzie seniorów?

Kiedyś wszystkich łącznie z sobą wysyłałem na szkolenia. Teraz uważam, że już nie warto - można prościej i łopatologiczniej pisać serwery.

Jeszcze jedno uzupełnienie - JavaEE, a szczególnie jej główny kawałek EJB powstały aby można było robić rozproszone transakcje. To
główny problem jaki ta architektura miała rozwiązać. Moja firma "chodzi" na JavaEE. Rozproszone transakcje musiano wywalić już dawno... (podobno systemy umierały).

0
margor90 napisał(a):):

"JEE jest open-source, ale własnościowe serwery aplikacyjne to porażka"

Ale styl wydawania tego jest powolny, zbieranie community itp.
Po prostu jest to za wolno wydawane. Ile można czekać na Java EE 8 ?

0

Z dwojga złego wolę świat Springa ;)

0

W aplikacji będą powiadomienia użytkownika ( dotyczące pojawienia się nowego wpisu w bazie danych), teraz pytanie jak to ogarnąć aby było wydajne. Bazy danych na serwerach będą połączone w klastrze i dane będą zreplikowane na każdy z nich.

  1. Odpytywanie bazy co jakiś czas tylko o nowe wpisy po dacie i przesyłanie do wszystkich podpiętych użytkowników.
  2. Trochę bardziej skomplikowany ale czy nie bardziej wydajny? Serwery będą się łączyć do serwera głównego który będzie miał także mechanizm rozsyłania nowych danych pomiedzy serwery podrzędne (każdy nowy wpis będzie wysłąny do każdego oraz od każdego). Taki manewr pozwoliłby uniknąć odpytywania bazy co jakiś czas, ale czy nie obciąży niepotrzebnie serwera głównego do rozsyłania danych pomiędzy węzłami?
0

Raczej jak dodajesz ten magiczny wpis do bazy to od razu publikujesz jakiś event, który mogą pozostałe serwery nasłuchiwać (topic) i dopiero wtedy jazda do websocketa.
Jak i czym zrobisz te eventy to inna para kaloszy. (To, że masz websockety i jakieś powiadomienia, a nie masz jeszcze mechanizmu messagingu, to raczej znaczy, że zabrałeś się od d... strony i masz nieadekwatną architekturę do problemu (czyli jak wszyscy :-) ).

0

He he, na razie jestem na etapie zbierania wiedzy :D W sumie co do rozprowadzania powiadomień miedzy serwery, chciałem załatwić to tak że główny serwer ma aktywny mechanizm do którego łączą się pozostałe serwery (przy pomocy websocketa). Tylko jeśli ten główny serwer padnie to wtedy tracimy rozprowadzanie powiadomień. Masz jakiś pomysł jak to załatwić wydajnie i niezawodnie ? :P

0

Jak byś chciał messaging dość niezawodny to możesz spojrzeć na:
https://www.rabbitmq.com/features.html (ale to jedna z setek możliwości).

Jakbyś chciał jakąś "niezawodność" systemu... to podaj ile masz milionów euro i co chcesz zrobić - zobaczymy :-)
Przede wszystkim podaj jaka niezawodność jest Ci potrzebna.

0

Co do niezawodności to myślę że pomysł z load balancing na poziomie DNS będzie dobry (przekazywanie połączeń do serwerów z mniejszą ilościa aktualnie podpiętych klientów) też pozwoli na utrzymanie funkcjonalności kiedy jeden z nich padnie.

Jeśli chodzi o ciągłą komunikację client-server to najlepiej wybrać zwykłe sockety? (ServerSocket, Socket) czy WebSocket tutaj pojawia się mały problem w przypadku aplikacji na zwykłej Javie bo mamy tylko ServerSocket do którego nie podepnie się WebSocket, jak pożenić te dwa różne sockety?

1

Ja tam mam w Javie prosty do ogarnięcia Websocket z Ratpacka. https://ratpack.io/manual/current/api/ratpack/websocket/WebSockets.html
Możesz też spojrzeć na http://sparkjava.com/documentation.html#websockets - ale ten drugi nie podoba się.

0

A co sądzisz o Jetty? Podobny jest do tego Spark'a

0

Odnośnie PubSub messagingu to... Kafka jest teraz trendy...
Ale mi osobiście wydaje się dość dużym kalibrem.

Z dokumentacji:
"n comparison to most messaging systems Kafka has better throughput, built-in partitioning, replication, and fault-tolerance which makes it a good solution for large scale message processing applications."

wiec przed użyciem zastanowiłbym się 3 razy.

0

Czy Node jest tylko stworzone do czatów i nie stawia się prostych blogów, witryn w nim. Tylko nadal będzie klepać to w PHP, Ruby i Pythonie?

0

Jeszcze takie pytanie jak zrobic w bezpiecznysposob logowanie przez websocketa. Chodzi mi oto ze dane logowania czyli login i haslo mialo bybyc wysylane przez websocketa gdzie potem aplikacja kilenta otrzyma session id do dalszej weryfikacji itd tylko jak to zrobic aby nikt nie orzechwicil danych ?

1 użytkowników online, w tym zalogowanych: 0, gości: 1