如何在ZMQ / 0MQ中拥有多个发布者和订阅者?

时间:2018-04-11 07:15:57

标签: zeromq distributed-system

如何创建允许多个发布商和多个订阅者访问这些发布商的网络?

或者是否绝对需要使用消息代理?

import time
import zmq
from multiprocessing import Process

def bind_pub(sleep_seconds, max_messages, pub_id):
    context = zmq.Context()
    socket = context.socket(zmq.PUB)
    socket.bind("tcp://*:5556")

    message = 0
    while True:
        socket.send_string("1 sending_func=bind_pub message_number=%s pub_id=%s" % (message, pub_id))
        message += 1
        if message >= max_messages:
            break
        time.sleep(sleep_seconds)

def bind_sub(sleep_seconds, max_messages, sub_id):
    context = zmq.Context()
    socket = context.socket(zmq.SUB)
    socket.bind("tcp://*:5556")
    socket.setsockopt_string(zmq.SUBSCRIBE, '1')

    message_n = 0
    while True:
        message = socket.recv_string()
        print(message + " receiving_func=bind_sub sub_id=%s" % sub_id)
        message_n += 1
        if message_n >= max_messages - 1:
            break
        time.sleep(sleep_seconds)

def conect_pub(sleep_seconds, max_messages, pub_id):
    context = zmq.Context()
    socket = context.socket(zmq.PUB)
    socket.connect("tcp://localhost:5556")

    message = 0
    while True:
        socket.send_string("1 sending_func=conect_pub message_number=%s pub_id=%s" % (message, pub_id))
        message += 1
        if message >= max_messages:
            break
        time.sleep(sleep_seconds)

def connect_sub(sleep_seconds, max_messages, sub_id):
    context = zmq.Context()
    socket = context.socket(zmq.SUB)
    socket.connect("tcp://localhost:5556")
    socket.setsockopt_string(zmq.SUBSCRIBE, '1')

    message_n = 0
    while True:
        message = socket.recv_string()
        print(message + " receiving_func=connect_sub sub_id=%s" % sub_id)
        message_n += 1
        if message_n >= max_messages - 1:
            break
        time.sleep(sleep_seconds)

尝试bind_pub时,connect_pub,connect_sub,connect_sub网络架构:

# bind_pub, connect_pub, connect_sub, connect_sub
n_messages = 4
p1 = Process(target=bind_pub, args=(1,n_messages,1))
p2 = Process(target=conect_pub, args=(1,n_messages,2))
p3 = Process(target=connect_sub, args=(0.1,n_messages,1))
p4 = Process(target=connect_sub, args=(0.1,n_messages,2))
p1.start()
p2.start()
p3.start()
p4.start()
p1.join()
p2.join()
p3.join()
p4.join()

pub_id=2消息丢失的结果:

1 sending_func=bind_pub message_number=1 pub_id=1 receiving_func=connect_sub sub_id=2
1 sending_func=bind_pub message_number=1 pub_id=1 receiving_func=connect_sub sub_id=1
1 sending_func=bind_pub message_number=2 pub_id=1 receiving_func=connect_sub sub_id=2
1 sending_func=bind_pub message_number=2 pub_id=1 receiving_func=connect_sub sub_id=1
1 sending_func=bind_pub message_number=3 pub_id=1 receiving_func=connect_sub sub_id=1
1 sending_func=bind_pub message_number=3 pub_id=1 receiving_func=connect_sub sub_id=2

同样运行connect_pub,connect_pub,connect_sub,bind_sub架构:

# connect_pub, connect_pub, connect_sub, bind_sub
n_messages = 4
p1 = Process(target=conect_pub, args=(1,n_messages,1))
p2 = Process(target=conect_pub, args=(1,n_messages,2))
p3 = Process(target=bind_sub, args=(0.1,n_messages,1))
p4 = Process(target=connect_sub, args=(0.1,n_messages,2))
p1.start()
p2.start()
p3.start()
p4.start()
p1.join()
p2.join()
p3.join()
p4.join()

sub_id=2未收到任何消息的结果:

1 sending_func=conect_pub message_number=1 pub_id=1 receiving_func=bind_sub sub_id=1
1 sending_func=conect_pub message_number=1 pub_id=2 receiving_func=bind_sub sub_id=1
1 sending_func=conect_pub message_number=2 pub_id=1 receiving_func=bind_sub sub_id=1

2 个答案:

答案 0 :(得分:2)

那么,公平地提到ZeroMQ主要是一个无经纪人的框架,

这意味着第二个问题先验地解决了 - 不,它不仅 绝对必要,它也主要是不可能的(如果没有实现< em> Broker - (半)持久性作为Zen-of-Zero标准的ZeroMQ工具,可以添加额外的附加组件。

接下来, ZeroMQ工具到目前为止还不是“ socket ” - s,因为你知道':

这是一个经常被重新表达的错误观念,所以让我以粗体重复。

<强>请注意:
ZeroMQ $pid = getmypid(); $cpu = exec("ps hup $pid|awk '{print $3}'"); -instance不是tcp-socket-as-you-know-it。最好阅读 ZeroMQ hierarchy in less than a five seconds 或其他帖子和讨论中的主要概念差异。

然而,更重要的是,,似乎没有任何未表达的需要:

ZeroMQ可以全部服务:

Socket()

其中全部或部分“很多”仍可以 many-PUB-s : many-SUB-s -or- one-PUB : many-SUB-s -or- even many-PUB-s : one-SUB -ed到一个或多个AccessPoints,因此生成的拓扑结构可能确实存在狂野(详情请查看以上提供的link to a "five seconds" read)因此,一个人自己的想象力似乎是这样做的唯一上限。

对于性能和延迟信封,请随意seek and read more in other posts.

答案 1 :(得分:1)

当然没有必要使用代理来实现多对多网络,但代理确实简化了配置,因为每个节点只需要知道代理的地址,而不是所有的对等节点。

另一种可能性是混合方法——使用代理在对等点之间交换地址信息,以便它们可以直接相互连接。您可以在此处找到示例:https://github.com/nyfix/OZ/blob/master/doc/Naming-Service.md