入门的读书笔记,目前为止一行zeroMQ的代码都没写过。
zero是立足更高抽象层次的通信组件,它试图向开发者提供一个基于角色的通信系统开发模式,在这些模式里,看不到socket/port/listen/accept,也不用关心I/O过程,通信方的角色定义才是关键因素。
zeroMQ不兼容现有的协议格式,它使用自己的协议。因此你没法用它写一个HTTP服务器,但是可以用来实现任何自定义协议。——说白了就是双方都要基于zeroMQ进行通信吧,说的这么绕。
zeroMQ在后台实现自己的I/O线程。zmq_init (1)的1意思是只有一个。——那就意味着开发者无需使用传统的多线程对socket连接进行管理的方式,从而简化了设计。无论多个线程/每线程若干个socket,或者最土气的每个socket对应一个线程的方式,都可以排除在设计范畴之外。
统一的socket API,特性包括:与具体传输模式无关(进程间/进程内/TCP/多播),自动重新连接节点,消息队列可缓存至磁盘,自动在后台线程进行I/O操作,自动管理socket错误,无锁的数据结构避免了死锁、等待、同步和信号量等问题。
核心消息模式。zeroMQ的模式是对以往成功的实践经验的抽象,有以下3种模式:
- 请求-应答,可以连接多个客户端,因此是1:N的;
- 订阅-发布,多个客户端可以连接多个发布者,是N:M的;
- 管道,一入一出(跟蜕化到1:1的订阅-发布模式似乎没有什么差别)。
消息一旦发送后不得再次访问,也不能再次发送。
支持消息分片,并给予如下保证:要么收到,要么收不到,不会出现部分发送;会延迟不确定的时间发送消息而不是立即发送;可以发送0长度消息。如果要发送文件,请预先分段读取再发送; 消息使用结束后必须调用zmq_msg_close(3)将其关闭,zeroMQ不会自动析构消息。采用
zmq_send (socket, &message, ZMQ_SNDMORE(如果是最后一个,此数字为0))
来发送分片消息;接收时则需要
int64_t more;
size_t more_size = sizeof (more);
zmq_getsockopt (socket, ZMQ_RCVMORE,&more, &more_size);
if (!more)
break;//Last message part
zeroMQ的device:一个类似于消息路由或者中介的概念,能够进行消息转发,通常是无状态的。内建的device有:QUEUE(请求-响应模式中介)、FORWARDER(订阅-发布模式中介)、STREAMER。
zeroMQ的多线程约束:1> 不能在线程间共享数据;2> 必须为进程创建上下文并传递给threads;3> zeroMQ的socket不能线程间共享!
持久化和暂时性的socket:略
可信的请求-应答:略
个人观点:关注于角色抽象的zeroMQ很不错,但是仅仅适用于可以套用这些模式的场合,在千变万化的企业消息传输需求前恐怕力有未逮。窃以为将其比较核心的设施抽取出来在私有模块中运用比较合理。例如背景线程、无锁数据结构、持久性消息缓存等等。之前曾经浏览过ICE(Internet Communications Engine),ICE的定义更为高层,提供了分布式、服务透明、业务均衡、面向对象等高级特性,类似于COBRA的精炼升级版本。在电信业务中恐怕是很难有用武之地的——国际电联的专家们脑子里没有那么高级的概念……从这个意义上来看,企业级通信需求已经大大超越了电信级业务的需求,在逻辑层次上也高出不少。如果在后者里需要消息传输,一个能够满足传输需求的基本通信模块足矣。这个时候,zeroMQ的内建机制更有用处些。