【问题标题】:How to control the source IP address of a ZeroMQ packet on a machine with multiple IPs?如何在具有多个 IP 的机器上控制 ZeroMQ 数据包的源 IP 地址?
【发布时间】:2018-03-18 19:33:47
【问题描述】:

Python 标准库的 socket.create_connection() 方法有一个源地址选项,用于控制连接使用的源 IP。

如果机器有多个地址,我如何使用 Python ZeroMQ 套接字做同样的事情?

在这种情况下,我一直使用 Linux 的 iproute2 ip addr add 创建地址和 ZeroMQ PUB/SUB socket-archetypes。

【问题讨论】:

  • 我不认为我完全理解您要解决的问题......接口上有特定的子网,路由应该决定从哪里出去,如果他们不这样做选择哪一个真的很重要吗?
  • 我正在测试第 3 层负载平衡,因此源 IP 地址决定了流量的终点。

标签: python linux zeromq


【解决方案1】:

嗯,ZeroMQ 读作 socket-"counterparty" 有点棘手(它不是)

为什么?

Classical socket 是免费资源。

ZeroMQ 是一个相当复杂的思想和行为原则(更好的分布式行为)层次结构,有助于设计智能分布式计算系统,而无需触及控制实际事件流的低级(ZeroMQ 抽象良好)细节在恶劣条件下的风暴中,所有分布式计算系统都是开放的(并且必须相应地在低级别进行处理,如果 ZeroMQ“承诺”要保留的高级抽象要实现并让设计人员的思想集中注意力而不是在他/她的核心应用程序部分,而不是重新设计轮子(通过所有试验和错误)来拉动 O/S 资源和摇动系统服务以收集一些低垂的水果)。


由于这些原因最好直接忘记 ZeroMQ 是“类似的东西-socket


ZeroMQ 层次结构不到五秒

1:
ZeroMQ 承诺可以轻松重用一些简单的可扩展正式通信模式archetypes,提供特定的分布式行为{ PUB/SUB | PUSH/PULL | PAIR/PAIR | XPUB/XSUB | ... | REQ/REP }

2:
除了只使用 device-less inproc:// 传输类的情况外,在所有其他情况下,ZeroMQ 需要一个或多个可调“引擎" - Context( nIOthreads = N )N >= 1

3:
有了这个,任何(未来的socket接入点都可以被实例化,从出生的那一刻起就具有行为原型:

aSubscribeCHANNEL = aLocalCONTEXT.socket( zmq.SUB )      # this is NOT a <SOCKET>
#                                 ^^^^^^__________________ even it was typed in

4:
在本地“引擎”“内部”准备好“Access Point”实例后,可以使用一个或多个(是,更多...哇!意味着更多的传入拉弦进入/从单个接入点“行为节点”吹出的哨声)调用以下任一方法:
.bind( @ 987654330@ )

.connect( &lt;transport-class&gt;://&lt;a-class-specific-address&gt; )

5:
当且仅当 .bind()-RTO-ready 接入点 A“被访问”由具有任何匹配行为配对的第一个实时 .connect()-RTO-ready 接入点 B,ZeroMQ-消息传递/信令原型开始生效(将其命名为 socket 可能是出于历史原因,以便及时解释)

PUB/PUB 永远不适合,原因很明显,而PUB/SUB 和许多其他行为原型对将非常匹配并形成相互“兼容”的行为,最终将上线并保持这样)


那么,
如果给定一台具有多个地址的机器,我该如何使用 Python ZeroMQ 套接字做同样的事情?

只需在对
.bind( "{ tcp | pgm | epgm }://&lt;ip&gt;:&lt;port#&gt;" ) 方法的调用中使用完全限定的规范,您就完成了。

就这么简单。

很酷,不是吗?

在性能调整、延迟削减和安全调整的背后还有许多令人惊喜的惊喜。

【讨论】:

  • 这个答案很有帮助,但事实证明我的问题不太清楚:我需要在connect方法中为连接的另一端绑定源ip。我已经为此效果添加了答案并对此表示赞同。
  • 很高兴您发现它有帮助。 .connect() 的工作方式与 .bind()-method 的工作方式相同。重要而酷的是,一个 [Access Point] 可以.connect( "tcp://&lt;address&gt;:&lt;port&gt;" ).connect( "vmci://@:&lt;port&gt;" ).connect( "ipc://&lt;address_identifier&gt;" ) 并在同一个 [Access Point] 的正式沟通行为模型。 这就是详细说明上述所有细节的原因,开始了解 ZeroMQ 套接字的不同之处以及它们为高级分布式系统带来的巨大力量。
【解决方案2】:

当尝试.connect()到远程时,我在protocol documentation中找到了答案,将源ip放在连接字符串中的分号之前:

rc = zmq_connect(socket, "tcp://192.168.1.17:5555;192.168.1.1:5555")

在 Python 中,这看起来像:

socket = zmq.Context().socket(zmq.SUB)
socket.connect('tcp://192.168.1.17:5555;192.168.1.1:5555')

【讨论】:

  • 分号分隔的列表扩展是 ZeroMQ 核心的“隐藏”API 特性的副作用。它在功能上创建与对.connect()-方法的一系列调用相同的东西,无论第一个是否使用tcp:// transport-class 和另一个epgm:// 一个,如解释的那样以上。
猜你喜欢
  • 2015-01-13
  • 2016-12-01
  • 2011-01-30
  • 2013-01-06
  • 1970-01-01
  • 2020-07-02
  • 1970-01-01
  • 1970-01-01
  • 2011-09-09
相关资源
最近更新 更多