1、zmq概述

ZeroMQ是一种基于消息队列的多线程网络库,其对套接字类型、连接处理、帧、甚至路由的底层细节进行抽象,提供跨越多种传输协议的套接字。引用云风的话来说:ZeroMQ 并不是一个对 socket 的封装,不能用它去实现已有的网络协议。它有自己的模式,不同于更底层的点对点通讯模式。它有比 tcp 协议更高一级的协议。(当然 ZeroMQ 不一定基于 TCP 协议,它也可以用于进程间和进程内通讯)它改变了通讯都基于一对一的连接这个假设。ZeroMQ 把通讯的需求看成四类。其中一类是一对一结对通讯,用来支持传统的 TCP socket 模型,但并不推荐使用。常用的通讯模式只有三类:
  1. 请求回应模型。由请求端发起请求,并等待回应端回应请求。从请求端来看,一定是一对对收发配对的;反之,在回应端一定是发收对。请求端和回应端都可以是 1:N 的模型。通常把 1 认为是 server ,N 认为是 Client 。ZeroMQ 可以很好的支持路由功能(实现路由功能的组件叫作 Device),把 1:N 扩展为 N:M (只需要加入若干路由节点)。从这个模型看,更底层的端点地址是对上层隐藏的。每个请求都隐含有回应地址,而应用则不关心它。
  2. 发布订阅模型。这个模型里,发布端是单向只发送数据的,且不关心是否把全部的信息都发送给订阅端。如果发布端开始发布信息的时候,订阅端尚未连接上来,这些信息直接丢弃。不过一旦订阅端连接上来,中间会保证没有信息丢失。同样,订阅端则只负责接收,而不能反馈。如果发布端和订阅端需要交互(比如要确认订阅者是否已经连接上),则使用额外的 socket 采用请求回应模型满足这个需求。
  3. 管道模型。这个模型里,管道是单向的,从 PUSH 端单向的向 PULL 端单向的推送数据流。

更多关于zeromq的解释,以及zeromq的功能请参考下面几个链接

ØMQ(ZeroMQ)简介 ,ØMQ - The Guide ,ZeroMQ 的模式

2、zmq架构

2.1、zmq整体架构

zeromq几乎所有I/O操作都是异步的,每个zmq i/o 线程(与实际线程不同)都有与之绑定的Poller,Poller采用经典的Reactor模式实现,Poller根据不同操作系统平台使用不同的网络I/O模型(select、poll、epoll、devpoll、kequeue等)。在zeromq中,zmq_socket也被看成是一个zmq io线程。每个线程内含一个信箱,用于线程与线程间传递命令(后面会详细讲),在创建zmq io线程时,会把信箱句柄加到Poller中,用于监听是否有命令到达。当client端开始发起连接或者server端开始监听时,会在主线程创建zmq_connector或者zmq_listener,主线程使用zmq_socket的mailbox发送命令给io线程,将其绑定到io线程中,io线程会把zmq_connector或者zmq_listener含有的句柄加入Poller中,以侦听读写事件。Client端与Server端都是通过Session来管理连接和通信,一个session代表一次会话,每个Session都会关联到相应的读/写管道, 主线程收发消息只是分别从管道中读/写数据。Session并不实际跟kernel交换I/O数据,而是通过plugin到Session中的Engine来与kernel交换I/O数据。

2.2zmq内部架构

zmq的内部架构涉及到zmq全局变量的管理,并发模型,线程模型(主线程,i/o线程,回收线程,zmq_socket线程,存活于线程中的对象),对象回收模型(对象树),消息的组织等,要想比较顺手的读懂源码,还是需要先了解一下这些结构,在zmq的官方站点已经给出来了详细的讲解,也有前辈进行了翻译:

Internal Architecture of libzmqZeroMQ的内部架构

http://www.aosabook.org/en/zeromq.html<摘录>开源软件架构-ZeroMQ

3、zmq基本流程

下面这幅zmq的基本流程图有助于整体把握zmq的流程,这幅图是由前辈总结的,来源于ZeroMQ研究与应用分析,(不知道是否是原创,有很多一样的博文,分不清原创是谁),不过新版的zmq已经不建议使用zmq_init初始化上下文语境了,新版建议使用zmq_new来创建上下文,关于新版zmq的一个详细流程在第4节会给出。

4、zmq对象交互

序列图有助于理解对象状态变迁,下图描述的是客户端的对象状态变迁。zmq_socket以ZMQ_REQ模式实例化,用以进行tcp通信:

void *requester = zmq_socket (context, ZMQ_REQ);
zmq_connect (requester, "tcp://localhost:5555");

4、zmq类层次

①、object_t,主要用于发送命令和处理命令,所有继承object_t的子类都具备该类的功能

②、io_thread_t,内含一个poller,可监听句柄的读、写、异常状态,继承自object_t,具有接收命令、处理命令、发送命令的功能

③、io_object_t,可以获取一个io_thread_t的poller,从而具备poller功能,所有继承自该类的子类都具有pollere功能,可监听句柄的读、写、异常状态

④、reaper_t,zmq的回收线程

⑤、own_t,zmq的对象树结点,或者说多叉树的结点,其主要用于对象的销毁,可以想到,对象的销毁就是这棵树的销毁过程,必须要使用深度优先的算法来销毁。关于zmq对象树在Internal Architecture of libzmq有详细讲解

⑥、tcp_connector_t,zmq_socket的连接器,使用她来建立tcp连接

⑦、tcp_listener_t,zmq_socket的监听器

⑧、stream_engine,负责处理io事件中的一种----网络事件,把网络字节流转换成zeromq的msg_t消息传递给session_base_t。另外一些和版本兼容相关的杂务也stream_engine处理的。stream_engine_t处理完杂务,到session_base_t就只看见msg_t了。

⑨、session_base_t,管理zmq_socket的连接和通信,主要与engine进行交换

⑩、socket_base_t,zeromq的socket,在zmq中,被当成一种特殊的”线程“,具有收发命令的功能

参考资料

ØMQ(ZeroMQ)简介

ØMQ - The Guide

ZeroMQ 的模式

Internal Architecture of libzmq

ZeroMQ的内部架构

http://www.aosabook.org/en/zeromq.html

<摘录>开源软件架构-ZeroMQ

libzmq master

zeromq源码分析笔记之架构(1)的更多相关文章

  1. zeromq源码分析笔记之线程间收发命令(2)

    在zeromq源码分析笔记之架构说到了zmq的整体架构,可以看到线程间通信包括两类,一类是用于收发命令,告知对象该调用什么方法去做什么事情,命令的结构由command_t结构体确定:另一类是socke ...

  2. zeromq源码分析笔记之无锁队列ypipe_t(3)

    在上一篇中说到了mailbox_t的底层实际上使用了管道ypipe_t来存储命令.而ypipe_t实质上是一个无锁队列,其底层使用了yqueue_t队列,ypipe_t是对yueue_t的再包装,所以 ...

  3. zeromq源码分析笔记之准备(0)

    zeromq这个库主要用于进程通信,包括本地进程.网络通信,涉及到一些基础知识,主要包括管道通信,socket编程的内容,反应器模式(使用IO多路复用实现),无锁队列这几块比较重要的部分,下面的几个链 ...

  4. ReentrantReadWriteLock源码分析笔记

    ReentrantReadWriteLock包含两把锁,一是读锁ReadLock, 此乃共享锁, 一是写锁WriteLock, 此乃排它锁. 这两把锁都是基于AQS来实现的. 下面通过源码来看看Ree ...

  5. ArrayList源码分析笔记

    ArrayList源码分析笔记 先贴出ArrayList一些属性 public class ArrayList<E> extends AbstractList<E> imple ...

  6. ROCKETMQ源码分析笔记1:tools

    rocketmq源码解析笔记 大家好,先安利一下自己,本人男,35岁,已婚.目前就职于小资生活(北京),职位是开发总监. 姓名DaneBrown 好了.我保证本文绝不会太监!转载时请附上以上安利信息. ...

  7. 线程池之ThreadPoolExecutor线程池源码分析笔记

    1.线程池的作用 一方面当执行大量异步任务时候线程池能够提供较好的性能,在不使用线程池的时候,每当需要执行异步任务时候是直接 new 一线程进行运行,而线程的创建和销毁是需要开销的.使用线程池时候,线 ...

  8. Android源码分析笔记--Handler机制

    #Handler机制# Handler机制实际就是实现一个 异步消息循环处理器 Handler的真正意义: 异步处理 Handler机制的整体表述: 消息处理线程: 在Handler机制中,异步消息处 ...

  9. jQuery 2.0.3 源码分析core - 整体架构

    拜读一个开源框架,最想学到的就是设计的思想和实现的技巧. 废话不多说,jquery这么多年了分析都写烂了,老早以前就拜读过, 不过这几年都是做移动端,一直御用zepto, 最近抽出点时间把jquery ...

随机推荐

  1. Flask源码阅读笔记(一)

    作者:acezio链接:https://zhuanlan.zhihu.com/p/21358368来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. flask的url r ...

  2. T-SQL表联接查询

    由于实践不足,总是忘记SQL Server 联接表查询的细节,在这里记录以便查询. 一.交叉联接 交叉联接仅执行一个罗辑查询处理阶段——笛卡尔积.也就是说,将一个输入表的每一行与另一个表的所有行匹配. ...

  3. linux 命令行更新sdk

    ./android list sdk --proxy-host android-mirror.bugly.qq.com --proxy-port 8080 --no-ui -a -s ./androi ...

  4. NSSet和NSMutableSet 确保数据的唯一性--备

    NSSet和NSMutableSet是无序的, 但是它保证数据的唯一性.当插入相同的数据时,不会有任何效果.从内部实现来说是hash表,所以可以常数时间内查找一个数据. 1.NSSet的使用 [NSS ...

  5. Linux C 调用MYSQL API 函数mysql_escape_string()转义插入数据

    Title:Linux C 调用MYSQL API 函数mysql_escape_string()转义插入数据 --2013-10-11 11:57 #include <stdio.h> ...

  6. sybase 备份和恢复

    use master go dump transaction MBFEWKDB with no_log go dump transaction MBFEHISDB with no_log go use ...

  7. delphi7开发webservice部属在apache服务器中 转

    delphi7开发webservice部属在apache服务器中 delphi7 webservice apache 用Delphi7开发Web Service程序,并把服务程序放在apache We ...

  8. HDU-4857(拓扑排序)

    Problem Description 糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排成一行. 现在有n个人,从1标号到n.同时有一些奇怪的约束条件,每个都形如:a必须在b之前. ...

  9. Bozo排序

    Bogo的变种,继续卖萌... Bogo每次都随机打乱数组,而Bozo每次随机选择两个位置,然后交换这两个位置的值.相同的是不断靠概率不断查看有序了没... public static void bo ...

  10. 数据库中的schema概念

    原文地址:http://blog.sina.com.cn/s/blog_7952e89001010jlj.html 数据库的初学者往往会对关系型数据库模式(schema).数据库(database). ...