Socket.io Websockets na TCP skonfigurowany Amazon Elastic Load Balancer

Planuję założyć grupę serwerów aplikacji NodeJS działających Socket.io na EC2 i chciałbym użyć Elastic Load Balancer do rozłożenia obciążenia między nimi. Wiem, że ELB nie obsługuje Websockets po wyjęciu z pudełka, ale mogę użyć konfiguracji opisanej tutaj w scenariuszu 2 .

Jak opisano w blogu , jednak zauważyłem, że ta konfiguracja nie oferuje powinowactwa sesji ani informacji o źródle IP:

Nie możemy mieć powinowactwa sesji ani X-Forward headers z tą konfiguracją ponieważ ELB nie parsuje wiadomości HTTP, więc niemożliwe jest dopasuj pliki cookie, aby zapewnić powinowactwo sesji ani wstrzykiwać specjalne X-nagłówki do przodu.

Will Socket.io nadal pracujesz w takich okolicznościach? Czy jest inny sposób na posiadanie zestawu Socket.io serwery aplikacji za load balancer z SSL?

EDIT: Tim Caswell mówi o robieniu tego już tutaj . Czy są jakieś posty wyjaśniające jak to skonfigurować? Znowu jest nie ma tu lepkości sesji, ale wszystko wydaje się działać dobrze.

Na marginesie, czy sticky sessions jest rzeczywiście konieczne z websockets? Czy informacje są przesyłane jako nowe i oddzielne wnioski, czy istnieje tylko jedno żądanie + połączenie, które przenosi wszystkie informacje?

Author: Giovanni Cappellotto, 2012-11-13

4 answers

Możesz teraz korzystać z nowej aplikacji load balancer uruchomionej niedawno przez AWS.

Wystarczy zastąpić ELB (obecnie Klasyczny load balancer) ALB (Application load balancer) i włączyć sticky sessions.

ALB obsługuje gniazda sieciowe. To powinno załatwić sprawę.

Https://aws.amazon.com/blogs/aws/new-aws-application-load-balancer/

Http://docs.aws.amazon.com/elasticloadbalancing/latest/application/introduction.html

 12
Author: anurag_29,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-18 08:00:44

Socket.io nie działa po wyjęciu z pudełka nawet z TCP ELB, ponieważ wykonuje dwa żądania HTTP przed uaktualnieniem połączenia do websockets.

Pierwsze połączenie jest używane do ustanowienia protokołu, ponieważ socket.io obsługuje więcej niż tylko websockets.

GET /socket.io/1/?t=1360136617252 HTTP/1.1
User-Agent: node-XMLHttpRequest
Accept: */*
Host: localhost:9999
Connection: keep-alive

HTTP/1.1 200 OK
Content-Type: text/plain
Date: Wed, 06 Feb 2013 07:43:37 GMT
Connection: keep-alive
Transfer-Encoding: chunked

47
xX_HbcG1DN_nufWddblv:60:60:websocket,htmlfile,xhr-polling,jsonp-polling
0

Drugie żądanie jest używane do aktualizacji połączenia:

GET /socket.io/1/websocket/xX_HbcG1DN_nufWddblv HTTP/1.1
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: MTMtMTM2MDEzNjYxNzMxOA==
Host: localhost:9999

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: 249I3zzVp0SzEn0Te2RLp0iS/z0=

W powyższym przykładzie widać, że xX_HbcG1DN_nufWddblv jest kluczem współdzielonym pomiędzy żądaniami. To jest problem. ELBs robi round-robin routing, czyli żądanie aktualizacji trafia na serwer, który nie uczestniczył w początkowych negocjacjach. W związku z tym serwer nie ma pojęcia, kim jest klient.

Stanowe dane w pamięci są wrogiem równoważenia obciążenia. Na szczęście, socket.io obsługuje używanie Redis do przechowywania danych. Jeśli łączysz redis z wieloma serwerami, zasadniczo współdzielą one sesje wszystkich klientów.

Zobacz socket.io strona wiki aby uzyskać szczegółowe informacje na temat konfiguracji Redis.

 15
Author: Jacob Groundwater,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-06 18:27:44

Jak wspomniałem w poście, używamy tylko ELB do zakończenia ssl i równoważenia obciążenia w klastrze serwerów HTTP-proxy, które obsługują websockety. ELB nie rozmawia bezpośrednio z serwerami websocket. Klaster proxy HTTP obsługuje wyszukiwanie w prawo socket.io serwer do podłączenia do zapewnienia lepkości sesji.

 5
Author: Tim Caswell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-14 15:42:43

Gdy uruchamiasz serwer w chmurze, który ma load-balancer/reverse proxy, routery itp., musisz skonfigurować go tak, aby działał poprawnie, zwłaszcza gdy skalujesz serwer, aby używał wielu instancji.

Jeden z ograniczeń Socket.io, SockJS i podobne biblioteki mają to, że muszą stale rozmawiać z tą samą instancją serwera. Działają doskonale, gdy istnieje tylko 1 instancja serwera.

Gdy skalujesz aplikację w środowisku chmurowym, obciążenie balancer (Nginx w przypadku Cloud Foundry) przejmie kontrolę, A żądania będą wysyłane do różnych instancji, powodując Socket.io złamać.

Aby pomóc w takich sytuacjach, load balancers mają funkcję o nazwie "sticky sessions" aka "powinowactwo sesji". Główną ideą jest to, że jeśli ta właściwość jest ustawiona, to po pierwszym żądaniu load-balanced wszystkie poniższe żądania trafią do tej samej instancji serwera.

W Cloud Foundry, sesje sticky oparte na plikach cookie są włączone dla aplikacji to ustawia cookie jsessionid.

Uwaga: jsessionid jest nazwą pliku cookie powszechnie używaną do śledzenia sesji w aplikacjach Java/Spring. Cloud Foundry po prostu przyjmuje to jako lepki plik cookie sesji dla wszystkich frameworków.

Więc wszystko, co aplikacje muszą zrobić, to ustawić plik cookie o nazwie jsessionid, aby socket.io praca.

App.use (cookieParser); ok.użycie (wym.session ({store:sessionStore, key:'jsessionid', secret:'your secret here'}));

Więc są to kroki:

Express ustawia plik cookie sesji o nazwie jsessionid. Kiedy socket.io łączy, używa tego samego pliku cookie i trafia do load balancer Load balancer zawsze kieruje go do tego samego serwera, na którym plik cookie został ustawiony. Jeśli używasz aplikacji Load Balancer, Sticky session settings jest na poziomie grupy docelowej

 -1
Author: Asif Saeed,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-15 06:19:16