我们什么时候应该在 zmq ROUTER 套接字中绑定多个客户端

When should we bind multiple clients in the zmq ROUTER socket

考虑下面的示例 ZMQ 代理程序:

def startBroker ():
# Prepare our context and sockets
    context = zmq.Context()
    frontend = context.socket(zmq.ROUTER)
    backend = context.socket(zmq.DEALER)
    frontend.bind("tcp://*:5555")
    frontend.bind("tcp://*:5558")
    backend.bind("tcp://*:5556")
    backend.bind("tcp://*:5557")

    # Initialize poll set
    poller = zmq.Poller()
    poller.register(frontend, zmq.POLLIN)
    poller.register(backend, zmq.POLLIN)

    # Switch messages between sockets
    while True:
        socks = dict(poller.poll())

    if socks.get(frontend) == zmq.POLLIN:
        message = frontend.recv_multipart()
        backend.send_multipart(message)

    if socks.get(backend) == zmq.POLLIN:
        message = backend.recv_multipart()
        frontend.send_multipart(message)

前端绑定多个socket需要考虑哪些参数?

frontend.bind("tcp://*:5555")

ROUTER进程中一个socket可以请求多少个?

将多个套接字绑定到前端是否理想?

似乎对您的代码在做什么有误解。

frontend = context.socket(zmq.ROUTER)

该代码创建一个 ROUTER 套接字并将其存储在 frontend 中。 frontend 现在是 ROUTER 套接字。

frontend.bind("tcp://*:5555")
frontend.bind("tcp://*:5558")

该代码 bind() 将单个套接字连接到多个端点。我认为在对 bind() 的一次调用中有不同的语义来执行此操作,但 this link 似乎表明您按照此处的方式进行操作。

不能将多个套接字绑定到同一个端点。您会收到该地址正在使用中的错误消息。在您的情况下,如果您确实需要两个套接字,您将必须执行以下操作,具体细节在很大程度上取决于您的特定用例:

context = zmq.Context()
frontend1 = context.socket(zmq.ROUTER)
frontend2 = context.socket(zmq.ROUTER)
backend1 = context.socket(zmq.DEALER)
backend2 = context.socket(zmq.DEALER)
frontend1.bind("tcp://*:5555")
frontend2.bind("tcp://*:5558")
backend1.bind("tcp://*:5556")
backend2.bind("tcp://*:5557")

...但是,如果没有 运行,我不建议在单个套接字上解决无法解决的特定问题(我想这就是您的问题第一名 - 在底部回答)。

在我开始之前,你的经纪人在这里充当一个简单的转发代理,并且有更直接的 ZMQ 语义来实现 zmq_proxy(),你可以看到示例 here,此处复制的相关位:

context = zmq.Context()

# Socket facing clients
frontend = context.socket(zmq.ROUTER)
frontend.bind("tcp://*:5559")

# Socket facing services
backend  = context.socket(zmq.DEALER)
backend.bind("tcp://*:5560")

zmq.proxy(frontend, backend)

# We never get here…
frontend.close()
backend.close()
context.term()

...该代码以更 "ZMQ appropriate" 的方式完成了与您的代码所做的 相同的事情。此示例代码来自 ZMQ Guide,整个指南中有大量带有 Python 代码的示例,我强烈建议您阅读它。


所以,这是问题的答案(转述)"When should a developer choose to use more than one socket to serve a specific service need":

很少。理论上,单个 ZMQ 套接字每秒可以处理 百万 条消息。消息大小很重要,当然,您受到连接带宽的限制,并且在内存中移动内容不是免费的,但理论上单个 ZMQ 套接字可以处理大多数一般工作负载。如果你想负载平衡,你通常会启动一个新进程,也许在一个完整的独立主机上,但它可能会在同一进程中启动第二个套接字,这取决于你的阻塞点是什么 - 它可能是在 ZMQ 套接字之前的一些其他系统资源,但该决定将来自您的应用程序的细节。

因此,一般来说,从单个插槽开始,尽可能多地利用它,当您发现可以通过水平扩展来提高性能时,请查看具体情况以确定最佳方案这样做的方法。