【发布时间】:2019-07-20 03:09:53
【问题描述】:
我需要构建一个实时低延迟的消息传递系统。
我阅读了 ZeroMQ 指南,因为我的要求 ROUTER-DEALER 模式完全匹配。我围绕它构建了系统,它运行良好。但是当我进行性能测试时,我发现 ZeroMQ 延迟非常高。
libzmq 版本:4.2.5
./local_lat tcp://127.0.0.1:5555 1 1000
./remote_lat tcp://127.0.0.1:5555 1 1000
message size: 1 [B]
roundtrip count: 1000
average latency: 26.123 [us]
当消息数很高时,ZeroMQ 的性能很棒,但是当相同的消息数为 1 时,延迟非常高。
./local_lat tcp://127.0.0.1:5555 1 1
./remote_lat tcp://127.0.0.1:5555 1 1
message size: 1 [B]
roundtrip count: 1
average latency: 506.500 [us]
我仍然不相信我将 ZeroMQ 指南中的 PUB-SUB 示例修改为 ROUTER-DEALER 并添加了时间戳并再次测试。还有延迟真的很高。这使得 ZeroMQ 无法使用。我同意,当消息量很大时,没有什么可以击败 ZeroMQ,但是对于即使单个消息 ZeroMQ 失败,延迟也很关键的系统。
注意:我也运行了 PUB-SUB 示例,它显示了相同的延迟数据
发件人.cpp
#include <zmq.hpp>
#include <stdlib.h>
#include <unistd.h>
#include <iostream>
#include <sys/time.h>
int main () {
// Prepare our context and publisher
zmq::context_t context (1);
zmq::socket_t publisher (context, ZMQ_ROUTER);
publisher.bind("tcp://*:5556");
//wait for peer to connect
//once connected store the identity to send message later
zmq::message_t identity,m;
publisher.recv(&identity);//identity
publisher.recv(&m);//message
sleep(1);//sleep to set up connections
struct timeval timeofday;
int i=1;//no of messages to send
while (i) {
zmq::message_t id,message("10101",5);
id.copy(&identity);
gettimeofday(&timeofday,NULL);
publisher.send(id,ZMQ_SNDMORE);
publisher.send(message);
std::cout << timeofday.tv_sec << ", " << timeofday.tv_usec << std::endl;
usleep(1);
--i;
}
return 0;
}
reciever.cpp
#include <zmq.hpp>
#include <iostream>
#include <sys/time.h>
int main (int argc, char *argv[])
{
zmq::context_t context (1);
zmq::socket_t subscriber (context, ZMQ_DEALER);
subscriber.setsockopt(ZMQ_IDENTITY,"1",1);
subscriber.connect("tcp://localhost:5556");
struct timeval timeofday;
subscriber.send(" ",1);
int update_nbr;
int i=1;
for (update_nbr = 0; update_nbr < i; update_nbr++) {
zmq::message_t update;
subscriber.recv(&update);
gettimeofday(&timeofday,NULL);
std::cout << timeofday.tv_sec << ", " << timeofday.tv_usec << std::endl;
}
return 0;
}
发送方输出
1562908600, 842072
接收器输出
1562908600, 842533
如您所见,大约需要 400 毫秒。
有什么办法可以减少延迟?
【问题讨论】:
-
您是否介意添加一份来自实时系统详细规范文档的副本或引用,实际设计目标是什么,定义可接受的消息传递延迟范围(对于最坏情况条件和其他工作负载信封) - 即,在原始实时系统详细规范文档中实际设置了对此类延迟范围的明确要求和/或在实施此类要求的要求中定义了哪些其他设计方面的约束实时系统行为?
-
@user3666197 不,我不能提供任何文件。重要的是消息应该以尽可能低的延迟从模块 A 流向 B。这是一个对时间非常敏感的应用程序。无论什么延迟都在这里巨大的。当消息量很大时,系统工作得非常好。问题只有当有单个消息时
-
问题很明确 - 不是提供“文档”,而是引用系统规范在要求中定义的消息传递延迟量(有多少 [us] 在保证实时系统,运行稳定并符合 RTS-DSpec 文档中的定义(更重要的是,当它是“一个非常时间敏感的应用程序”时 - 系统详细规范中的确切要求文档定义,这种延迟在规范内是什么,什么不是)。“没有目标,实际上任何道路都可能适合......”
-
这里到底有什么不清楚的地方? .我说进程 A 向进程 B 发送消息。收到 B 的消息大约需要 400 毫秒。理想情况下,延迟应该小于 150 毫秒。我提供了示例代码,您可以自己编译并检查延迟数据
-
任何解决方案或调整?
标签: centos ubuntu-16.04 zeromq