【问题标题】:Are there any Python 2.7 alternatives to ZeroMQ that are released under the BSD or MIT license?是否有根据 BSD 或 MIT 许可发布的 ZeroMQ 的 Python 2.7 替代品?
【发布时间】:2015-01-12 19:41:05
【问题描述】:

我正在寻找在 BSD 或 MIT 许可下发布的 ZeroMQ 的 Python 2.7 替代品。我正在寻找支持请求-回复和发布-订阅消息模式的东西。如有必要,我可以自己序列化数据。我从 Twisted Matrix Labs 找到了 Twisted,但它似乎需要一个阻塞事件循环,即 reactor.run()。我需要一个在后台运行并让我的应用程序检查某些事件的消息的库。还有其他选择吗?

【问题讨论】:

  • 您的应用程序使用了 ZeroMQ 的众多高级功能中的哪些?我认为回答这个问题会缩小你的问题范围。
  • 我已经更新了这个问题,但我不确定我是否已经解决了你的问题。总的来说,我的应用程序非常简单。我有一个正在执行长时间运行循环的进程。在每个循环结束时,它会记录一些数据。我想要第二个进程可以连接到第一个进程并查询该数据。对于第二个进程来说,必须等到第一个进程中循环的每次迭代结束,这是可以接受的。

标签: message-queue zeromq messaging pyzmq


【解决方案1】:

nanomsg,一个ZeroMQ的妹妹,一个尝试——同样的父亲,同样的美女

  • 是的,它是在 MIT/X11 许可下获得许可的。
  • 是的,REQ/REP - 允许构建无状态服务集群来处理用户请求
  • 是的,PUB/SUB - 将消息分发给大量感兴趣的订阅者
  • 有多个 Python 绑定可用

https://github.com/tonysimpson/nanomsg-python(推荐)

https://github.com/sdiehl/pynanomsg

https://github.com/djc/nnpy


nanomsg 和 ZeroMQ 的区别

(截至 2014/11 v0.5-beta 的状态 - 由 nanomsg.org >>> a-click-thru to the original HyperDoc 提供)

许可

nanomsg 库已获得 MIT 许可。这意味着,与 ZeroMQ 不同的是,您可以修改源代码并在不同的许可下重新发布它,作为专有产品等。有关许可的更多推理可以找到here

POSIX 合规性

ZeroMQ API 虽然以 BSD 套接字 API 为模型,但与 API 不完全匹配。 nanomsg 旨在完全符合 POSIX 标准。

套接字表示为整数,而不是空指针。 ZeroMQ 中已知的上下文在 nanomsg 中不存在。这意味着更简单的 API(可以在单个步骤中创建套接字)以及使用该库在单个进程中的不同模块之间进行通信的可能性(想想以不同语言实现的插件)。更多讨论可以找到here。 发送和接收函数(nn_sendnn_sendmsgnn_recvnn_recvmsg)完全匹配 POSIX 语法和语义。

实现语言

该库是用 C 而不是 C++ 实现的。

从用户的角度来看,这意味着不依赖于 C++ 运行时(libstdc++ 或类似的),这在受限和嵌入式环境中可能很方便。 从 nanomsg 开发人员的角度来看,它让生活更轻松。 由于使用了侵入式容器而不是 C++ STL 容器,内存分配的数量大大减少。 以上也意味着更少的内存碎片,更少的缓存未命中等。 有关 C 与 C++ 主题的更多讨论,请参见 herehere

可插拔传输和协议

在 ZeroMQ 中没有用于插入新传输(想想 WebSockets、DCCP、SCTP)和新协议(对应于 REQ/REPPUB/SUB 等)的正式 API。因此,自那时起就没有添加新传输2008. 也没有实施新的协议。正式的内部传输 API(请参阅 transport.hprotocol.h)旨在缓解问题,并作为创建和试验新传输和协议的基础。

请注意,这两个 API 仍然是新的,将来可能会进行一些调整,以使其可用于各种场景。

nanomsg 实现了一个新的SURVEY 协议。这个想法是向多个对等点发送消息(“调查”)并等待所有对等点的响应。有关更多详细信息,请查看文章here。也看here。 在金融服务中,使用“将消息从任何人传递给其他人”类型的消息传递是很常见的。为了解决这个用例,在 nanomsg 中实现了一个新的BUS 协议。查看详情here

线程模型

我在 ZeroMQ 中犯过的重大架构错误之一是它的线程模型。每个单独的对象都由单个线程专门管理。这对于工作线程处理的异步对象很有效,但是,对于用户线程管理的对象来说,它会成为一个麻烦。该线程可用于在任意时间跨度内执行不相关的工作,例如一个小时,在此期间,由它管理的对象完全卡住了。一些不幸的后果是:无法在REQ/REP 协议中实现请求重新发送,PUB/SUB 在应用程序执行其他工作时未应用订阅,等等。在 nanomsg 中,对象没有与特定线程紧密绑定,因此不存在这些问题。

ZeroMQ 中的REQ 套接字在实际环境中不能真正使用,因为如果由于服务失败或类似情况导致消息丢失,它们会卡住。用户必须改用XREQ 并自己实现请求重试。使用 nanomsg,重试功能内置于 REQ 套接字中。 在 nanomsg 中,REQREP 都支持取消正在进行的处理。只需发送一个新请求而不等待回复(在REQ 套接字的情况下)或获取一个新请求而不回复前一个请求(在REP 套接字的情况下)。 在 ZeroMQ 中,由于其线程模型,bind-first-then-connect-second 场景不适用于 inproc 传输。它固定在 nanomsg 中。 出于类似原因,自动重新连接不适用于 ZeroMQ 中的 inproc 传输。这个问题在 nanomsg 中也得到了解决。 最后,nanomsg 尝试使 nanomsg 套接字线程安全。虽然仍然不鼓励使用来自多个并行线程的单个套接字,但 ZeroMQ 套接字在这种情况下随机失败的方式被证明是痛苦且难以调试的。

状态机

nanomsg 库中的内部交互被建模为一组状态机。目的是避免 ZeroMQ 中出现的难以理解的关闭机制,从而使库的开发更容易。

更多讨论见herehere

IOCP 支持

ZeroMQ 中长期存在的问题之一是它在内部使用 BSD 套接字 API,即使在它是二等公民的 Windows 平台上也是如此。酌情使用 IOCP 将需要对代码库进行重大重写,因此,尽管多次尝试,但从未实现。 IOCP 应该具有更好的性能特征,更重要的是,它允许使用无法通过 BSD 套接字 API 访问的其他传输机制,例如 NamedPipes。由于这些原因,nanomsg 在 Windows 平台内部使​​用 IOCP。

级别触发的轮询

ZeroMQ 真正让用户感到困惑的一个方面是能够通过使用 ZMQ_FD 文件描述符将 ZeroMQ 套接字集成到外部事件循环中。混淆的主要来源是描述符是边缘触发的,即它仅在之前没有消息并且新消息到达时才发出信号。 nanomsg 使用级别触发的文件描述符,而不是在有可用消息时简单地发出信号,而不管它在过去是否可用。

路由优先级

nanomsg 实现出站流量的优先级。您可以决定将消息优先路由到特定目的地,并仅在主要目的地不可用时才回退到备用目的地。

更多讨论请见here

TCP 传输增强功能

对 TCP 传输有一个小的改进。连接时,您可以选择指定用于连接的本地接口,如下所示:

nn_connect (s, "tcp://eth0;192.168.0.111:5555").

异步 DNS

DNS 查询(例如将主机名转换为 IP 地址)以异步方式完成。在 ZeroMQ 中,此类查询是同步完成的,这意味着当 DNS 不可用时,整个库,包括未使用 DNS 的套接字,都会挂起。

零拷贝

虽然 ZeroMQ 提供“零拷贝”API,但它并不是真正的零拷贝。相反,它是“在消息到达内核边界之前的零复制”。从那时起,数据就像标准 TCP 一样被复制。另一方面,nanomsg 旨在支持真正的零复制机制,例如 RDMA(CPU 绕过,直接内存到内存复制)和 shmem (通过使用共享内存在同一盒子上的进程之间传输数据)。零拷贝消息传递的 API 入口点是 nn_allocmsgnn_freemsg 函数以及传递给发送/接收函数的 NN_MSG 选项。

高效订阅匹配

在 ZeroMQ 中,简单的尝试用于存储和匹配 PUB/SUB 订阅。订阅机制适用于最多 10,000 个订阅,其中简单的 trie 运行良好。但是,有些用户使用了多达 150,000,000 个订阅。在这种情况下,需要更有效的数据结构。因此,nanomsg 使用内存高效版本的 Patricia trie 而不是简单的 trie。

更多详情请查看article

统一缓冲区模型

ZeroMQ 有一个奇怪的双缓冲行为。传出和传入数据都存储在消息队列中在 TCP 的 tx/rx 缓冲区中。例如,它的含义是,如果要限制传出数据量,则必须同时设置ZMQ_SNDBUFZMQ_SNDHWM 套接字选项。鉴于两者之间没有语义差异,因此 nanomsg 仅使用 TCP(或等效的)缓冲区来存储数据。

可扩展性协议

最后,在哲学层面上,nanomsg 旨在实现不同的“可扩展性协议”,而不是成为一个通用的网络库。具体来说:

不同的协议是完全分离的,您不能将REQ 套接字连接到SUB 套接字或类似的。 每个协议都体现了一个分布式算法,具有明确定义的先决条件(例如,在REQ/REP 的情况下,“服务必须是无状态的”)和保证(如果REQ 套接字保持活动状态,请求将被最终处理)。 部分故障由协议处理,而不是由用户处理。事实上,它对用户是透明的。 协议的规范在 /rfc 子目录中。 目标是通过 IETF 标准化协议。 没有通用的类似 UDP 的套接字 (ZMQ_ROUTER),您应该使用 L4 协议来实现这种功能。

【讨论】:

  • 非常好的和彻底的答案。可以说,甚至有点过度杀戮。 ;) 请注意,您的参考文献未链接。换句话说,您说了一些大意是“在此处查看更多信息”,但没有链接。
  • 你有没有一些关于纳米蜜蜂的发展进展,仍处于测试阶段?
猜你喜欢
  • 1970-01-01
  • 2020-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多