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

最佳答案

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。

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

实现语言

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

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

可插拔传输和协议

在ZeroMQ中,没有用于插入新传输(例如WebSocket,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中,由于其线程模型,“绑定先连接然后连接”场景不适用于Inproc传输。它以nanomsg固定。
由于类似的原因,自动重新连接不适用于ZeroMQ中的过程内传输。这个问题在nanomsg中也得到解决。
最后,nanomsg尝试使nanomsg套接字具有线程安全性。虽然仍然不鼓励从多个线程并行使用单个套接字,但是在这种情况下ZeroMQ套接字随机失败的方式被证明是痛苦且难以调试的。

状态机

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

有关更多讨论,请参见herehere

IOCP支持

ZeroMQ中的一个长期存在的问题是,即使在Windows平台上它是二等公民,它在内部也使用BSD套接字API。相反,适当地使用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函数,以及传递给send / recv函数的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协议来实现这种功能。

关于message-queue - 是否有BSD或MIT许可下发布的Python 2.7替代品ZeroMQ?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26946521/

10-12 20:37