ZeroMQ是什么?
按照官方的说法,是一个简单好用的传输层,像框架一样的一个socket library,他使得Socket编程更加简单、简洁和性能更高。是一个消息处理队列库,可在多个线程、内核和主机盒之间弹性伸缩。
“无需多说,ZeroMQ是一个雄心满满项目,该简介对于完整的特性集而言只能略见一斑。ZeroMQ的明确目标是“成为标准 网络协议栈的一部分,之后进入Linux内核”,现在还未看到它们的成功。但是,它无疑是极具前景的、并且是人们更加需要的“传统”BSD套接字之上的一 层封装。ZeroMQ让编写高性能网络应用程序极为简单和有趣。”
看了ZeroMQ的Guide文档后,我的理解是,这是个可以替代Socket的一系列接口,他跟socket的区别是:普通的socket是端到端的(1:1的关系),而ZeroMQ确实可以N:M的一个关系,人们对BSD套接字的了解较多的是点对点的连接。点对点连接需要显式地建立连接、销毁连接、选择协议(TCP/UDP)和处理错误等。
他的强大之处,在于他的几个网络拓扑结构(框架),基于他的多对多的关系,他有以下几个应用场景非常实用:
1. 请求回应模型。由请求端发起请求,并等待回应端回应请求。从请求端来看,一定是一对对收发配对的;反之,在回应端一定是发收对。请求端和回 应端都可以是 1:N 的模型。通常把 1 认为是 server ,N 认为是Client 。ZeroMQ 可以很好的支持路由功能(实现路由功能的组件叫作 Device),把 1:N 扩展为N:M (只需要加入若干路由节点)。从这个模型看,更底层的端点地址是对上层隐藏的。每个请求都隐含有回应地址,而应用则不关心它。
2. 发布订阅模型。这个模型里,发布端是单向只发送数据的,且不关心是否把全部的信息都发送给订阅端。如果发布端开始发布信息的时候,订阅端尚 未连接上来,这些信息直接丢弃。不过一旦订阅端连接上来,中间会保证没有信息丢失。同样,订阅端则只负责接收,而不能反馈。如果发布端和订阅端需要交互 (比如要确认订阅者是否已经连接上),则使用额外的 socket 采用请求回应模型满足这个需求。
3. 管道模型。这个模型里,管道是单向的,从 PUSH 端单向的向 PULL 端单向的推送数据流。
关于Libevent+PHP:
我们知道,Libevent是一个事件驱动库,可以实现异步调用,也具有不错的效率。而ZeroMQ本身也是一个异步的,可以并发的一个库,在Handling Multiple Sockets章节中介绍的示例程序中,可以看到,在一个进程中,可以开多个端口进行服务,而在client端,也可以同时连接多个server,而且不同于传统的做法是,ZeroMQ可以不借助libevent实现无阻塞的并发。
在Rasmus Lerdorf的PPT中有写到一段libevent+php的程序,在这篇文章(《关于php的libevent扩展的应用》)的基础上使用了ZeroMQ代替了Socket,事实上ZeroMQ确实比Socket要好用的多(至少官方是这么说的),还有些具体的讨论,有兴趣的同学可以去围观下。Rasmus的博客
关于未来的展望:
总之,ZeroMQ还是个很有潜力的项目,他是个非常强大的信息队列库,非常适合在订阅源到订阅者之间的信息推送,jober机器到集群(worker机器)任务的分配以及其他的应用,你不必关心太多的细节,他已经为你做好了。另外,你也不用担心,服务器或是客户端哪个先开机,你都不会丢失你的信息。在做服务器开发方面,他是再合适不过了,而且他支持很多语言,真的很多。但是对于1对1的通信,他其实是不推荐的,我们可以借用的地方是,如果引擎和qp服务器与php的通信之间,都是用这个库来写程序,可以实现不同程序间的信息传送,至于性能方面的比较,与当前的方式相比,还真没有太大的把握。