웹 소켓의 부하를 분산하는 방법에 대한 질문이 있습니다.
웹 소켓을 지원하는 서버가 있습니다. 브라우저는 내 사이트에 연결되고 각 브라우저는 www.mydomain.com
. 이렇게하면 내 소셜 네트워크 앱이 클라이언트에게 메시지를 푸시 할 수 있습니다.
전통적으로 HTTP 요청 만 사용하여 두 웹 서버 앞에 두 번째 서버와로드 밸런서를 추가하여 확장했습니다.
웹 소켓을 사용하는 경우 연결은로드 밸런서가 아닌 웹 서버와 직접 연결되어야합니다. 머신의 물리적 제한이 64k 개방 포트라고 말하고 클라이언트가로드 밸런서에 연결하는 경우 지원할 수 없기 때문입니다. 64k 명 이상의 동시 사용자.
그래서 어떻게-
-
페이지가로드 될 때 클라이언트가로드 밸런서가 아닌 웹 서버에 직접 연결하도록 하시겠습니까? 노드에서 JavaScript를로드하면 페이지가 처음 요청 될 때마다로드 밸런서 (또는 기타)가 스크립트의 URL을 임의로 수정합니까?
-
잔물결 시작 처리? 브라우저는 웹 서버가 종료됨에 따라 연결이 종료되었음을 알 수 있습니다. 연결을 다시 시도하는 JavaScript 코드를 작성할 수 있지만 노드는 잠시 사라질 것입니다. 그래서 사용할 다음 노드의 주소를 쿼리하려면로드 밸런서로 돌아 가야한다고 생각합니다.
-
브라우저가 처음에 요청
www.mydomain.com
하고www34.mydomain.com
. 노드가 다운 될 때까지 꽤 잘 작동합니다. 페이스 북과 같은 사이트는 그렇게하지 않습니다. 그들은 그걸 어떻게 햇어?
답변
소스 -IP- 포트 해시를 기반으로 IP 패킷을 WebSocket 서버 팜에 배포하는 L3로드 밸런서를 배치합니다. L3 밸런서는 상태를 유지하지 않기 때문에 (해시 된 소스 -IP 포트 사용) 로우 엔드 하드웨어 (예 : 10GbE)에서 유선 속도로 확장됩니다. 배포는 결정적이므로 (해시 된 소스 -IP- 포트 사용) TCP (따라서 WebSocket)에서 작동합니다.
또한 64k 하드 제한 은 지정된 (소스) IP 주소에 대해 나가는 TCP / IP 에만 적용됩니다 . 들어오는 TCP / IP에는 적용되지 않습니다. 2 코어, 4GB RAM VM에서 200k 활성 연결을 사용하여 Autobahn (고성능 WebSocket 서버)을 테스트했습니다 .
또한 초기 WebSocket 핸드 셰이크 중에 발표 된 HTTP 경로에서 L7로드 밸런싱을 수행 할 수 있습니다. 이 경우로드 밸런서는 상태를 유지해야합니다 (어떤 소스 IP- 포트 쌍이 어떤 백엔드 노드로 이동하는지). 그럼에도 불구하고 적절한 설정에서 수백만 개의 연결로 확장 될 것입니다.
면책 조항 : 저는 Autobahn의 원작자이며 Tavendo에서 일합니다.
답변
websocket 서버 로직이 socket.io가있는 nodejs에서 실행되는 경우 socket.io에 동기화를 위해 공유 redis 키 / 값 저장소를 사용하도록 지시 할 수 있습니다. 이렇게하면로드 밸런서에 대해 신경 쓰지 않아도되고 이벤트가 서버 인스턴스간에 전파됩니다.
var io = require('socket.io')(3000);
var redis = require('socket.io-redis');
io.adapter(redis({ host: 'localhost', port: 6379 }));
참조 : http://socket.io/docs/using-multiple-nodes/
그러나 어느 시점에서 나는 redis가 병목 현상이 될 수 있다고 생각합니다 …
답변
검사 및 “라우팅 기능”을 사용하여 레이어 7로드 밸런싱을 달성 할 수도 있습니다.
“Stingray Traffic Manager를 사용하여 WebSockets 트래픽을 검사하고 부하를 분산하는 방법과 필요한 경우 동일한 IP 주소 및 포트에서 수신되는 WebSocket 및 HTTP 트래픽을 관리하는 방법”을 참조하십시오. https://splash.riverbed.com/docs/DOC-1451