【发布时间】:2013-05-20 05:12:19
【问题描述】:
听起来在 ZeroMQ 中按照传统的 UNIX 套接字使用套接字是没有意义的。我基于对 ZeroMQ 的错误认知,为分布式搜索算法设计了一个架构。在我的程序中,有一个代理负责监控其他代理并收集他们的数据。真实数据将按照 PULL-PUSH 或 PUB-SUB 模式在代理之间传输。每个代理都有一个 PULL 套接字侦听传入消息。每条消息都包含一个 ID 号,用于指定发件人的身份。
在初始化阶段,监视器应该监听它的 REP 套接字。每个代理将连接到监视器众所周知的 REP 套接字并自我介绍(发送他的 ID 号和代理正在侦听的端口号)。监视器将有关代理的所有数据存储在三个字段的记录中:<ID, IP, port>。 (这就是我对 ZMQ 有问题的地方。)当一定数量的代理准备好时,监视器将所有数据(每个代理的 <IP,ID,port>)发送给所有代理。最后一步由代理和监视器之间的 PUB-SUB 模式完成。
这张图片可能有助于了解我想要实现的内容:
在上图中,监视器应该将它的表发送给每个人。关键问题是如何在 REQ-REP 模式中获取请求者(任何代理)的公共 IP 地址?所有代理都绑定到其本地主机 (127.0.0.1)。它们应该分布在任意数量的主机上。所以AFAIK他们需要知道彼此的公共IP。
在不存在解决方案的情况下,重新设计架构的任何帮助都是适当的。
更新
我能想到的一个候选解决方案是修改每个代理以绑定到他/她的公共 IP 而不是localhost。如果有一种获取公共 IP 地址的神奇方法,任何代理都可以将他的地址发送到监视器。
第二次更新
目前代理获取了自己的公网IP地址,并通过消息发送给服务器:
std::string AIT::ABT_Socket::getIP() {
std::string address = "";
FILE * fp = popen("ifconfig", "r");
if (fp) {
char *p = NULL, *e;
size_t n;
while ((getline(&p, &n, fp) > 0) && p) {
if (p = strstr(p, "inet addr:")) {
p += 10;
if (e = strchr(p, ' ')) {
*e = '\0';
return std::string(p);
address = std::string(p);
}
}
}
}
pclose(fp);
return address;
}
【问题讨论】:
-
澄清一下,您是说监视器需要知道代理的 IP 地址才能将其表发送给他们?
-
没有。监视器需要知道代理的 IP 地址,才能将这些 IP 地址发送给所有代理。换句话说,构建表。它可以发送消息,但它不知道使用 ZeroMQ 的 IP 地址:D
-
能否将每个代理的 IP 地址存储在配置文件中,或者只使用
ifconfig并解析出inet address来获取IP?然后每个代理可以在消息中将 IP 发送给监视器 -
@Raffian 这正是昨天在更新中提出的,并在今天实施。我昨晚实施的 :) 查看第二次更新
-
ZMQ 是独立于传输的,这就是为什么你无法找到某人的地址(可能不止一个地址)。如果您绝对必须让代理进行任意直接连接,那么您需要让他们将其地址作为元协议的一部分提交给监视器 - 还有一种方法可以将信息与给定的会话/连接相关联。我建议您加入 ZeroMQ 邮件列表并在那里提出问题,这是您最有可能从完全熟悉 ZMQ 的人那里获得帮助的地方。
标签: c++ parallel-processing zeromq agent