0

有没有人有任何实际场景对 ZMQ 套接字进行负载测试以获得最大数量。他们可以处理的“并发用户”(不是吞吐量)?看起来 ZeroMQ 在 FD 限制方面存在一些严重问题。

场景是:有许多 Web 服务器框架吹嘘他们可以处理数百万并发用户 - 现在如果 ZeroMQ 不能处理超过 FD_SETSIZE 没有。任何时间点的用户,对可扩展性都是一个非常严重的限制(因为FD不仅仅是进程资源,也是机器资源,所以在同一台机器上产生新进程没有意义)。

为了验证,我正在尝试加载测试 ZMQ_STREAM 以找出它可以维持多少并发用户。它是一个简单的“hello-world”响应服务器,它只监听 ZMQ_STREAM 并为每个请求返回“hello world”(严格接收后跟发送样式)。

现在,在使用 JMeter 进行测试时(使用 users=1000),点击断言:zmq_assert (fds.size () <= FD_SETSIZE). 这意味着什么?那个 ZMQ 持有 FD_SETSIZE 个 FD?但是(根据下面的代码)每个连接都会立即打开和关闭,我看不出有可能在任何时间点同时打开多个 FD。

问:如果是这样的话,任何基于ZMQ的应用程序实现百万用户并发连接的方式是什么?(除了让 1000 台机器每台处理 1000 个用户的明显且毫无意义的解决方案,或者将 FD_SETSIZE 增加到一个非常大的数字)

任何人都知道这些 FD 的使用方式和原因以及它们是如何耗尽的(更重要的是,其他框架,例如 nginx node.js 没有这个问题),请稍加说明。

服务器代码(如果重要)如下:

#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;
}

使用 JMeter,用户=1000

4

1 回答 1

1

What exactly do you mean when you say "each connection is opened and closed immediately"? You bind on a stream socket, which accepts incoming requests in the while loop, which runs perpetually and never closes anything. The call to zmq_close(socket); after the loop is never reached.

Even the last part of the message explicitly uses ZMQ_SNDMORE, which should keep the connection open waiting for more text. Presumably to allow a small number of clients a lower overhead for repeated connections, I guess. It should probably be:

zmq_send(socket, 0, 0, 0);

I don't know which of these issues would release the resources to allow a larger number of clients, if either, but probably it's an abuse of ZMQ (or at least misguided) to try and write an HTTP server in it or try to make it scale to millions of concurrent peers/clients.

node.js and nginx are event based concurrent I/O systems, they are significantly different architecturally from ZMQ, and they are made to solve different problems. Trying to make ZMQ into them is going about things the wrong way. What you probably want is to use node.js with socket.io, or if you're using it for HTTP then just use it's native http module.

于 2014-05-20T14:42:25.827 回答