C/C++编程:ZeroMQ架构

1060 篇文章 295 订阅

ZeroMQ概述

ZeroMQ是一种基于消息队列的多线程网络库,其对套接字类型、连接处理、帧、甚至路由的底层细节进行抽象,提供跨越多种传输类型的套接字。引用云风的话来说:ZeroMQ并不是一个对socket的封装、不能用它去实现已有的网络协议。它有自己的模式,不同于更底层的点对点通讯模式。它有比TCP协议更高一层的协议。(当然ZeroMQ 不一定基于TCP协议,它也可以用于进程和进程内的通信)它改变了通讯但是基于一对一的连接这个假设。ZeroMQ 把通讯的需求看成四类。一种一类是一对一结对通讯,同来支持传统的TCP socket模型,但并不推荐使用。常见的通讯模式只有三类:

  • 请求回应模型:
    • 由请求端发起请求,并等待回应端回应请求。
    • 请求端和回应端都可以是 1:N 的模型。通常把 1 认为是 server ,N 认为是 Client 。
    • ZeroMQ 可以很好的实现路由功能(实现路由的组件叫做Device),把:N扩展为N:M(只需要加入若干路由点)
    • 从这个模型看,更底层的端点地址是对上层隐藏的。每个请求都隐含有回应地址,而应用不关心它
  • 发布订阅模式:
    • 这个模型里,发布端是单向只发送数据的,而且不关心是否把全部的消息都发送给了订阅端
    • 如果发布端开始发布消息的时候,订阅端尚未连接上来,这些信息直接丢弃
    • 不过一旦订阅端连接上来,中间会保证没有信息丢失。
    • 同样,订阅端只负责接收,而不能反馈
    • 如果发布端和订阅端需要交互(比如要确认订阅者是否已经连接上),而使用额外的socket采用请求回应模型满足这个需求
  • 管道模型:在这个模型里面,管道是单向的,从 PUSH 端向 PULL 端单向的推送数据流。

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

ZeroMQ架构

ZeroMQ整体架构

ZeroMQ几乎所有IO操作都是异步的,每个ZeroMQ IO线程(与实际线程不同)都有与之绑定的Poller,Poller采用经典的Reactor模式实现,Poller根据不同的操作系统平台使用不同的网络IO模型(select、poll、epoll、devpoll、kequeue等)。在ZeroMQ中,zmp_socket也被看成是一个ZeroMQ IO线程。每个线程内含有一个信箱,用于线程与线程键传递命令。在创建ZeroMQ IO线程时,会把信箱句柄添加到Poller中,用于监听是否有命令到达。当客户端开始发起连接或者服务器开始监听时,会在主线程创建zmq_connector或者zmq_listener,主线程使用zmp_socketmailbox发送命令给IO线程,将其绑定到IO线程中,IO线程会把zmq_connector或者zmq_listener含有的句柄加入Poller中,以侦听读写事件。客户端与服务端但是通过session来管理连接和同学,一个session代表一次会话,每个session都会关联到相应的读/写通道,主线程收发消息只是分布从管道中读/写数据。session并不实际跟kernel交换IO数据,而是通过plugin到session中的engine来与kernel交换IO数据

在这里插入图片描述

ZeroMq内部架构

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

ZeroMQ基本流程

下面这幅zmq的基本流程图有助于整体把握zmq的流程,这幅图是由前辈总结的,来源于ZeroMQ研究与应用分析,不过新版的zmq已经不建议使用zmq_init初始化上下文语境了,新版建议使用zmq_new来创建上下文,关于新版zmq的一个详细流程在第4节会给出。
在这里插入图片描述

zmq对象交互

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

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

在这里插入图片描述

zmq类层次

在这里插入图片描述

  • object_t,主要用于发送和处理命令,所有继承object_t的子类都具备该类的功能
  • io_thread_t:内含一个poller,可以监听句柄的读、写、异常状态,继承自object_t,具有接收命令、处理命令、发送命令的功能
  • io_object_t:可以获得一个io_thread_t的poller,从而具备poller功能,所有继承自该类的子类都有poller功能,可以监听句柄的读、写、异常状态
  • reaper_t:zmq的回收线程
  • own_t:zmq的对象树结点,或者说多叉树的结点,其主要用于对象的销毁,可以想到,对象的销毁就是这棵树的销毁过程,必须要使用深度优先的算法来销毁。关于zmq对象树在Internal Architecture of libzmq有详细讲解
  • tcp_connect_t:zmq_socket的连接器,可以使用它来建立tcp连接
  • 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中,被当成一种特殊的”线程“,具有收发命令的功能
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值