为什么需要ZeroMQ
ZeroMQ可以分开来看Zero MQ,MQ就是Message Queue消息队列。Zero是零,它代表零中间件(None-Broker)、零延迟,同时,它又有了新的含义:零管理、零成本、零浪费。总的来说,零表示最小、最简,这是贯穿于该项目的哲理。致力于减少复杂程度,提高易用性。
消息队列有四个典型应用场景:
- 异步处理:任务并行,减少响应时间
- 应用解耦:无上下文,无状态,只通过消息通信
- 流量削锋:流量过大或暴增时,像个漏斗一样做缓冲
- 消息通讯:需要广播消息
与其它消息队列ActiveMQ, RabbitMQ, RocketMQ, NATS, NSQ, Kafka等相比,它的特点是:
- 无需中间代理(brokerless),如果需要也可以通过ZeroMQ自建一个broker。
- 高性能,吞吐上比其它高一个数量级
- 无消息持久化,进程关了消息会丢失
- 跨语言,跨平台
- 可单独部署,也可集成到应用中
- 可作为Socket通信库使用
什么是ZeroMQ
它不是一个中间件,而是一个底层的网络通讯库。在Socket API之上做了一层封装,将网络通讯、进程通讯和线程通讯抽象为统一的API接口。并且提供了多种应用模式。如,“请求/响应”,“发布/订阅”,“负载均衡”,“共享队列”,“服务的动态发现”等。
高性能的原因
1、无锁的队列模型
对于跨线程间的交互(用户端和session)之间的数据交换通道pipe,采用无锁的队列算法CAS;在pipe两端注册有异步事件,在读或者写消息到pipe的时,会自动触发读写事件。
2、批量处理的算法
对于传统的消息处理,每个消息在发送和接收的时候,都需要系统的调用,这样对于大量的消息,系统的开销比较大,zeroMQ对于批量的消息,进行了适应性的优化,可以批量的接收和发送消息。
3、多核下的线程绑定,无须CPU切换
区别于传统的多线程并发模式,信号量或者临界区, zeroMQ充分利用多核的优势,每个核绑定运行一个工作者线程,避免多线程之间的CPU切换开销。
使用的协议
inproc(进程内)、ipc(进程间)、tcp、pgm(广播)、epgm(广播)
ZeroMQ支持四个层次的通信:进程内,跨进程,跨节点,跨网络。在节点和网络层需要指定IP地址或域名,如:
backend.Bind("tcp://10.1.1.0:8100")
线程和进程通信,可以自定义,如:
workers.Bind("inproc://workers")
使用的模式
内置的四种消息模式:
- Request-reply:请求-响应,其实就是RPC
- Pub-sub:发布-订阅,用于内容分发
- Pipeline:管道,用于扇入扇出,并发任务的分发与收集
- Exclusive pair:两个套接字的一对一连接,用于线程间通信。
ZeroMQ的套接字类型
-
REQ/REP: 请求响应
-
PUSH/PULL: push是发送,pull是接收。PUSH会将消息分发给所有连接,分担任务,达到负载均衡。
-
PAIR:一对一的,用于线程间通信
-
DEALER/ROUTER: 分发与路由,主要用于共享队列。请求响应的路由与分发
-
PUB/SUB: 发布订阅,消息发给所有感兴趣的连接
-
XPUB/XSUB:主要用于服务的动态发现。XSUB and XPUB are exactly like SUB and PUB except they expose subscriptions as special messages.
-
STREAM:
使用场景
- rpc: 远程过程调用,使用REQ/REP类型套接字,一问一答。
- 消息分发:使用PUB/SUB类型套接字。
- 中间件/代理:转发消息,用于拓展网络和规模。
- 负载均衡:使用PUSH/PULL套接字,消息分发到不同的worker
- 服务动态发现
- 共享队列:使用DEALER/ROUTER套接字。