2012-04-11 40 views
6

Buduję system rozproszony, który składa się z potencjalnie milionów klientów, którzy wszyscy muszą zachować otwarte (najlepiej HTTP) połączenie, aby czekać na polecenie z serwera (który działa gdzie indziej) . Obciążenie wiadomości/poleceń nie będzie bardzo wysokie, może jeden komunikat/s/1000 klientów, co oznacza, że ​​będzie to 1000 ms/s przy 1 milionie klientów. => zasadniczo chodzi o równoczesne połączenia.push serwera dla milionów współbieżnych połączeń

Wymagania są również proste. Jeden sposób przesyłania wiadomości (serwer-> klient), tylko 1 klient na "kanał".

Jestem całkiem otwarty pod względem technologii (xmpp/websockets/comet/...). Używam Google App Engine jako serwera, ale ich "kanały" nie będą działać dla mnie niestety (zbyt niskie limity i żaden klient Java). XMPP był opcją, ale jest dość drogi. Do tej pory korzystałem z pobierania URL-a & pubnub, ale właśnie zaczęły one pobierać opłaty za połączenia (czas duży).

Więc:

  1. Czy ktoś wie o usługi, które obecnie nie może zrobić to za mnie w przystępny sposób? Najczęściej znalazłem ograniczenie lub wysokie opłaty za połączenia.

  2. Jakieś doświadczenie z wdrożeniem takiego serwera samodzielnie? Już to zrobiłem i działa całkiem nieźle (na podstawie Tomcat & NIO), ale nie miałem jeszcze czasu, aby skonfigurować środowisko testowe dużego obciążenia (częściowo dlatego, że jest to nadal rozwiązanie awaryjne, wolałbym bitowy serwer msg). Jakiekolwiek doświadczenie, ilu użytkowników dostajesz na GB? Jakieś twarde ograniczenia?

Moja architektura umożliwia również fragment serwery MSG, ale chciałbym, aby zmaksymalizować równoczesnych połączeń, ponieważ napowietrznych przetwarzania CPU MSG jest minimalne.

+0

Ten jest trudniejszy do zaakceptowania. Czy rozważałeś protokół bezpołączeniowy, taki jak UDP? Będziesz musiał napisać własne protokoły potwierdzenia, ale wtedy nie będziesz musiał utrzymywać połączeń i nie będziesz musiał ponosić kosztów połączenia. Napisałem kilka bardzo rozproszonych serwerów rozproszonych, ale nie klientów. – Gray

+0

FYI, mam zaimplementowałem go za pomocą netty (zobacz odpowiedź poniżej). – Daniel

+0

Cool @Daniel. Muszę to sprawdzić. Słyszałem dobre rzeczy o Netty, ale nigdy go nie użyłem. – Gray

Odpowiedz

6

W międzyczasie zaimplementowałem własny serwer wiadomości przy użyciu netty.io. Netty korzysta z Java NIO i bardzo dobrze skaluje. W przypadku bezczynnych połączeń otrzymuję ślad pamięci o wielkości 500 bajtów na połączenie. Robię tylko bardzo proste przekazywanie wiadomości (bez buforowania, przechowywania lub innych wymyślnych rzeczy), ale z łatwością otrzymuję 1000 - 1500 ms/s (każde pół KB) na małej instancji amazonka (1ECU/1.6GB).

W przeciwnym razie, jeśli szukasz usługi (płatnej), mogę polecić spire.io (nie pobierają opłat za połączenia, ale mają wyższą cenę za wiadomość) lub pubnub (pobierają opłaty za połączenia, ale są tańsze za wiadomość).

3

Trzeba spojrzeć bardziej w architekturę tworzenia takiego środowiska. Przede wszystkim, jeśli samodzielnie zapiszesz zarządzanie gniazdami, nie używaj wątku na gniazdo klienta. Użyj metod asynchronicznych do odbierania i wysyłania danych. WebSockets może być zbyt duże, jeśli twoje wiadomości są małe. Ponieważ implementuje ramkowanie, które musi być zastosowane do każdej wiadomości dla każdego gniazda oddzielnie (buforowanie może być używane dla różnych wersji protokołów WebSockets), co powoduje, że wolniej przetwarzają oba kierunki: do odbierania i wysyłania, zwłaszcza z powodu maskowania danych .

Możliwe jest tworzenie milionów gniazd, ale tylko najbardziej zaawansowane technologie są w stanie to zrobić. Erlang jest w stanie obsłużyć miliony połączeń i jest dość skalowalny. Jeśli chcesz mieć miliony połączeń za pomocą innych technologii wyższego poziomu, musisz pomyśleć o grupowaniu tego, co próbujesz osiągnąć.

Na przykład przy użyciu serwera bramy, który będzie śledzić wszystkie serwery przetwarzania. I mieć ich dane (IP, porty, obciążenie (jeśli będzie to jedna wewnętrzna sieć, firewall i port forwarding może być przydatny tutaj). Oprogramowanie klienckie łączy się z tym serwerem bramy, serwer bramy sprawdza najmniej obciążony serwer i wysyła adresy IP i port do klienta Klient tworzy połączenie bezpośrednio z działającym serwerem przy użyciu podanego adresu W ten sposób będziesz miał bramę, która również będzie obsługiwać autoryzację i nie będzie utrzymywała połączeń przez długi czas, więc jeden z nich może wystarczyć. publikowanie danych i utrzymywanie połączeń

Jest to bardzo związane z Twoimi potrzebami i może nie być odpowiednie dla Twoich rozwiązań.

+0

Znalazłem interesujący artykuł na ten temat: http://www.metabrew.com/article/a-million-user-comet-application-with-mochiweb-part-1 Może być interesujące, że autorowi udało się zoptymalizuj ślad memu, używając biblioteki języka C, która obsługuje połączenia, aby zastąpić erlang. – Daniel

+0

Maksimi Mihejevs: można u. Odpowiedź na następujące pytanie, byłoby to pomocne dla mnie. Thanks.http: //stackoverflow.com/questions/23597203/instant-messaging-over-xmpp-or-websocket – Pradeep

Powiązane problemy