有没有人有任何真实场景,负载测试ZMQ套接字最大的没有。他们可以处理的“并发用户”(非吞吐量)?看起来ZeroMQ在FD限制方面存在一些严重问题。
场景是:有许多网络服务器框架,他们可以处理数百万并发用户 - 现在如果ZeroMQ无法处理超出FD_SETSIZE的数量。在任何时候用户都是一个非常严格的可扩展性限制(因为FD不仅仅是流程资源,还有机器资源,因此在同一台机器上产生新流程毫无意义。)
要验证,我正在尝试加载测试ZMQ_STREAM以查找它可以维持多少并发用户。它是一个简单的“hello-world”响应服务器,它只监听ZMQ_STREAM并为每个请求返回“hello world”(严格接收后跟send风格)。
现在,在使用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,users = 1000
答案 0 :(得分:1)
当您说“每个连接立即打开和关闭”时,您的意思是什么?绑定在stream
套接字上,该套接字接受while
循环中的传入请求,该循环永久运行并且永远不会关闭任何内容。永远不会达到循环后对zmq_close(socket);
的调用。
即使邮件的最后一部分明确使用ZMQ_SNDMORE
,也应该保持连接打开等待更多文本。我想可能是为了让少数客户在重复连接时的开销更低。应该是:
zmq_send(socket, 0, 0, 0);
我不知道哪些问题会释放资源以允许更多客户端(如果有的话),但可能是滥用ZMQ(或至少被误导)尝试在其中编写HTTP服务器或尝试使其扩展到数百万并发的同伴/客户端。
node.js和nginx是基于事件的并发I / O系统,它们在架构上与ZMQ有很大不同,它们用于解决不同的问题。试图让ZMQ进入它们是错误的方式。您可能想要的是将node.js与socket.io一起使用,或者如果您将其用于HTTP,那么只需使用它的本机http
模块。