2012-04-11 3 views
6

서버 (다른 곳에서 실행되는 명령)를 기다리기 위해 열린 (선호하는 HTTP) 연결을 유지해야하는 수백만의 클라이언트로 구성된 분산 시스템을 구축 중입니다. . 메시지/명령로드는 매우 높지 않을 것입니다. 즉, 1 메시지/초/1000 클라이언트 즉, 100 만 건당 1 백만 건의 클라이언트를 의미합니다. => 기본적으로 동시 연결에 관한 것입니다.수백만 개의 동시 연결을위한 서버 푸시

요구 사항도 간단합니다. 편도 메시징 (서버 -> 클라이언트), "채널"당 하나의 클라이언트.

저는 기술면에서 꽤 열려 있습니다 (xmpp/websockets/comet/...). Google App Engine을 서버로 사용하고 있지만 불행히도 (채널 할당량이 너무 적어 Java 클라이언트가 없음) "채널"이 작동하지 않습니다. XMPP는 옵션 이었지만 비용이 많이 듭니다. 지금까지 URL 가져 오기 & pubnub를 사용했지만 연결 (큰 시간)을 청구하기 시작했습니다.

그래서 :

는 는
  1. 사람은 저렴한 방법으로 저를 위해 그렇게 할 수 밖에 서비스를 알고 있나요? 대부분의 경우 연결을 제한하거나 과도하게 청구 한 것으로 나타났습니다.

  2. 이러한 서버를 직접 구현 한 경험이 있습니까? 나는 실제로 그것을 이미 완료했으며 꽤 잘 작동한다 (Tomcat & NIO 기반). 그러나 아직 실제로는 대형 부하 테스트 환경을 설정하는 데 시간이 없었습니다. (부분적으로 이것은 대체 솔루션이기 때문에 부분적으로는 선호합니다. 전투 강화 된 메시지 서버). GB 당 몇 명의 사용자를 대상으로 한 경험이 있습니까? 하드 한도가 있습니까?

내 아키텍처에서는 msg 서버를 조각 낼 수도 있지만 msg 처리 CPU 오버 헤드가 적기 때문에 동시 연결을 최대화하고 싶습니다.

+0

이 하나는 받아 들일 수있는 더 강하다. UDP와 같은 비 연결형 프로토콜을 고려 했습니까? 자신 만의 ack 프로토콜을 작성해야하지만 연결을 유지할 필요가 없으므로 연결 오버 헤드가 발생하지 않아도됩니다. 매우 높은 처리량의 분산 서버를 작성했지만 고객은 직면하지 않았습니다. – Gray

+0

참고로, 나는 netty를 사용하여 구현했습니다 (아래 답변 참조). – Daniel

+0

쿨 다니엘. 나는 그것을 조사해야 할 것이다. 나는 Netty에 관해 좋은 말을 들었지만 결코 사용하지 않았다. – Gray

답변

6

나는 netty.io를 사용하여 자체 메시지 서버를 구현했습니다. Netty는 Java NIO를 사용하고 확장 성이 뛰어납니다. 유휴 연결의 경우 연결 당 메모리 바이트가 500 바이트가됩니다. 매우 간단한 메시지 전달 (캐싱, 스토리지 또는 다른 멋진 것들) 만하고 있지만 작은 아마존 인스턴스 (1ECU/1.6GB)에서 1000 - 1500 msg/sec (각 KB는 1/2)를 쉽게 얻을 수 있습니다.

그렇지 않은 경우 (유료) 서비스를 찾고 있다면 spire.io를 추천 할 수 있습니다 (연결 비용은 무료이지만 메시지 당 가격은 더 쌉니다) 또는 pubnub (연결 요금은 청구하지만 메시지 당 비용은 저렴합니다.)).

3

그런 환경을 만드는 아키텍처를 좀 더 살펴야합니다. 우선, 소켓 관리를 직접 작성하는 경우 클라이언트 당 소켓 스레드를 사용하지 마십시오. 데이터 수신 및 전송에 비동기 메서드를 사용합니다. 메시지가 작 으면 웹 소켓이 너무 무거울 수 있습니다. 각 소켓마다 개별적으로 적용해야하는 프레이밍을 구현하기 때문에 (캐싱은 서로 다른 버전의 WebSockets 프로토콜에 사용할 수 있음) 수신 및 송신에 대한 처리 속도가 느려집니다. 특히 데이터 마스킹 때문입니다. .

수백만 개의 소켓을 만들 수 있지만 대부분의 고급 기술 만이 그렇게 할 수 있습니다. Erlang은 수백만 개의 연결을 처리 할 수 ​​있으며 확장 성이 뛰어납니다. 다른 고급 기술을 사용하여 수백만 건의 연결을 원한다면 달성하려는 대상의 클러스터링에 대해 생각해 봐야합니다.

예를 들어 모든 처리 서버를 추적하는 게이트웨이 서버를 사용합니다. 그리고 그것들의 데이터 (IP, 포트,로드 (하나의 내부 네트워크가 될 경우 방화벽 및 포트 포워딩이 여기에 편리 할 것입니다.) 클라이언트 소프트웨어가 해당 게이트웨이 서버에 연결하면 게이트웨이 서버는로드가 가장 적은 서버를 확인하고 ip 및 포트를 클라이언트에 연결 클라이언트는 제공된 주소를 사용하여 작동중인 서버에 직접 연결을 만듭니다. 그런 식으로 인증을 처리 할 수있는 게이트웨이를 갖게되고 오래 동안 연결을 유지하지 않으므로 그 중 하나만으로 충분할 수 있습니다. 데이터 게시 및 연결 유지

이것은 사용자의 요구와 매우 관련이 있으며 솔루션에 적합하지 않을 수 있습니다.

+0

그 주제에 대한 흥미로운 기사를 찾았습니다 : http://www.metabrew.com/article/a-million-user-comet-application-with-mochiweb-part-1 erlang을 대체 할 커넥션을 처리하는 C lib를 사용하여 mem footprint를 최적화하십시오. – Daniel

+0

Maksims Mihejevs : 다음 질문에 대한 답변을 주시면 도움이 될 것입니다. 감사합니다 .http : //stackoverflow.com/questions/23597203/instant-messaging-over-xmpp-or-websocket – Pradeep