2014-05-13 2 views
0

ZMQ 소켓을 최대한로드 할 수있는 실제 시나리오가있는 사람이 있습니까? 처리 할 수있는 '동시 사용자 수'(처리량 아님) ZeroMQ처럼 FD 한계에 심각한 문제가있는 것 같습니다.처리 할 수있는 최대 동시 사용자를 찾기위한 ZeroMQ (ZMQ_STREAM)로드 테스트

시나리오는 다음과 같습니다. 처리 할 수있는 수백만 명의 동시 사용자를 자랑하는 수많은 웹 서버 프레임 워크가 있습니다. 이제는 ZeroMQ가 FD_SETSIZE 번호 이상으로 처리 할 수없는 경우입니다. (즉, FD는 프로세스 자원이 아니라 기계 자원이기 때문에 동일한 시스템에서 새 프로세스를 생성 할 필요가 없기 때문에) 확장성에 대한 매우 심각한 제한 사항입니다.

확인하려면 테스트 ZMQ_STREAM을로드하여 동시 사용자 수를 확인하려고합니다. ZMQ_STREAM을 수신하고 모든 요청 ("send"다음에 엄격한 수신을 할 때)에 "hello world"를 반환하는 간단한 "hello-world"응답 서버.

이제 JMeter (사용자 = 1000 사용)로 테스트하는 동안 어설 션을 누르십시오 : zmq_assert (fds.size() <= FD_SETSIZE). 이것은 무엇을 의미합니까? ZMQ가 FD_SETSIZE 개의 FD를 보유하고 있습니까? 그러나 (아래 코드에 따라) 각 연결이 즉시 열리고 닫히기 때문에 어느 시점에 몇 개의 FD가 동시에 열릴 수 있는지를 알 수 없습니다.

질문 : 모든 ZMQ 기반 앱에 대해 백만 사용자 동시 연결을 달성하는 방법은 무엇입니까?

누구나 대해 아무것도 알고 (떨어져 1000 기계 각 처리 1000 명의 사용자를 가진, 또는 FD_SETSIZE 증가의 분명하고 의미 솔루션에서 미친 듯이 많은 일하기) 어떻게 그리고 왜이 FDS를 사용하고 어떻게 (그리고 더 중요한 것은 어떻게 nginx node.js와 같은 다른 프레임 워크가이 문제를 가지고 있지 않은지) 약간의 빛을 던져주세요.

서버 코드가 중요한 경우 다음과 같습니다 : JMeter를, 사용자를 사용

#include <zmq.h> 
#include <assert.h> 
#include <string.h> 
#include <iostream> 
int main(void) 
{ 
    void *ctx = zmq_ctx_new(); 

    void *socket = zmq_socket(ctx, ZMQ_STREAM); 
    int rc = zmq_bind(socket, "tcp://*:8080"); 
    uint8_t id[256]; 
    size_t id_size = 256; 
    char msg[4096]; 
    size_t msg_size = 4096; 
    int nCount = 0; 
    char http_response[] = 
     "HTTP/1.0 200 OK\r\n" 
     "Content-Type: text/plain\r\n" 
     "\r\n" 
     "Hello, World!"; 
    int nResponseLen = strlen(http_response); 
    while (1) { 
     id_size = zmq_recv(socket, id, 256, 0); 
     msg_size = zmq_recv(socket, msg, sizeof(msg), 0); 
     msg[msg_size] = '\0'; 
     std::cout << ++nCount << " -----\n"; 

     zmq_send(socket, id, id_size, ZMQ_SNDMORE); 
     zmq_send(socket, http_response, nResponseLen, ZMQ_SNDMORE); 

     zmq_send(socket, id, id_size, ZMQ_SNDMORE); 
     zmq_send(socket, 0, 0, ZMQ_SNDMORE); 
    } 
    zmq_close(socket); 
    zmq_ctx_destroy(ctx); 
    return 0; 
} 

= 1000

+0

사용중인 OS가 무엇입니까? https://zeromq.jira.com/browse/LIBZMQ-57 –

+0

OS는 windows입니다. 예, 해결 방법으로 FD_SETSIZE를 늘릴 수있는 가능성을 알고 있습니다. 그러나 최대의 목표를 달성하는 올바른 방법이 무엇인지 알아내는 데 더 많은 관심이 있습니다. 동시 연결 수 (ZMQ 및 가능한 경우 다른 프레임 워크가이 문제를 피한 방법). ZMQ 소켓의 각 연결된 클라이언트가 새로운 FD를 요구한다면, 우리는 옛날에 '클라이언트 당 하나의 스레드'스타일의 리소스가 부족한 서버 문제 (slashdot, c10k 등)의 게임으로 돌아 왔습니다. FD는 스레드보다 비용이 적지 만 여전히 확장 성 병목 현상이있을 수 있습니다. –

답변

1

당신이 말하는 "각 연결을 열 즉시 닫을 때"정확히 무엇을 의미합니까? stream 소켓에 바인딩하면 while 루프에서 수신 요청을 받아들이며 영구적으로 실행되고 절대로 아무것도 닫지 않습니다. 루프 후 결코 zmq_close(socket);에 대한 호출에 도달하지 않습니다.

메시지의 마지막 부분도 명시 적으로 ZMQ_SNDMORE을 사용하므로 더 많은 텍스트를 기다리는 연결을 열어 두어야합니다. 아마도 적은 수의 클라이언트가 반복 된 연결에 대한 낮은 오버 헤드를 허용 할 것으로 추측합니다.

zmq_send(socket, 0, 0, 0); 

나도 경우, 더 많은 클라이언트를 허용하도록 리소스를 해제 할 이러한 문제 중 어느 모르겠지만, 아마도 그것은에 ZMQ의 남용이다 (또는 적어도 잘못) : 아마해야 HTTP 서버를 시도해보십시오. 수백만 명의 동시 피어/클라이언트에 맞게 확장 해보십시오.

node.js와 nginx는 이벤트 기반 동시 입출력 시스템으로 구조적으로 ZMQ와는 구조가 다르며 다른 문제를 해결하기 위해 만들어졌습니다. 그들에게 ZMQ를 만들려고 시도하는 것은 잘못된 방식으로 진행됩니다. 당신이 원한다면 node.js를 socket.io와 함께 사용하거나, HTTP 용으로 사용한다면 그냥 native http 모듈을 사용하면된다.

+1

당신은 ZMQ가 이러한 종류의 일에 옳지 않다는 것에 대해 옳았습니다. 그러나 최근 ZMQ_ROUTER_RAW와 ZMQ_STREAM 소켓에 반대되는 주장은 거의 없었습니다. 따라서 부하 테스트를 통해 실제 작업을 수행 할 능력이 있는지 알아볼 수 있지만 지금까지는 증거를 찾을 수 없습니다. 연결과 ZMQ_SNDMORE에 관해서는, 몇 가지 이유로 그것이 예제가 어떻게 위임되었는지에 대한 것입니다 (이상한 결과를 낳지 않는 것에 대한 몇 가지주의 사항이 있음). 어쨌든, 목표는 ZMQ가 이러한 심각한 자원 제한을 가지고 있음을 확인하는 것입니다. ZMQ는 앞으로 나아갈 길이 멀다. –

+0

Gotcha, 의미있는 말이지만, "심각한 작업"으로 여기에서 수행되는 일만 자격을 부여하는 것을 망설이지 만 ... ZMQ가 합리적인 수의 피어/클라이언트와 함께 높은 메시지로드를 잘 처리 할 수 ​​있다는 것은 잘 알려져 있습니다 . ZMQ가 여기에서 목표로하는 작업 유형에 적합한 지에 대한 링크를 게시 하시겠습니까? – Jason

+0

[Pieter Hintjen의 블로그 항목] (http://hintjens.com/blog:42)에서 그가 코드를 작성한 곳 (그리고 맨 아래에 사용자의 의견이 표시되어 있음)에서 그는 확실히 'ZMQ_SNDMORE' 대신에'0'을 사용하여'send '합니다. 나는 C++ 바인딩에 문제가있을 수 있다고 생각한다. 어쨌든, 그 수정으로 시도하고 당신이 다른 결과를 얻을 수 있는지보십시오. – Jason