概述
1.ZeroMQ的背景介绍
官方:“ZMQ(以下ZeroMQ简称ZMQ)是一个简单好用的传输层,像框架一样的一个socket library,他使得Socket编程更加简单、简洁和性能更高。是一个消息处理队列库,可在多个线程、内核和主机盒之间弹性伸缩。与其他消息中间件相比,ZMQ并不像是一个传统意义上的消息队列服务器,事实上,它也根本不是一个服务器,它更像是一个底层的网络通讯库,在Socket API之上做了一层封装,将网络通讯、进程通讯和线程通讯抽象为统一的API接口。
ZMQ的明确目标是“成为标准网络协议栈的一部分,之后进入Linux内核”。现在还未看到它们的成功。但是,它无疑是极具前景的、并且是人们更加需要的“传统”BSD套接字之上的一层封装。ZMQ让编写高性能网络应用程序极为简单和有趣。”
它解决了应用程序需要在网络上实现良好弹性而无需花费太多成本的大多数问题。特别:
它在后台线程中异步处理I / O。它们使用无锁数据结构与应用程序线程通信,因此并发的ZeroMQ应用程序不需要锁,信号量或其他等待状态。组件可以动态变化,ZeroMQ将自动重新连接。这意味着用户可以按任何顺序启动组件。用户可以创建“面向服务的体系结构”(SOA),使服务可以随时加入和离开网络。它在需要时自动将消息排队。它会智能地进行此操作,在将消息排队之前将其推到尽可能靠近接收者的位置。它具有处理过多队列的方法(称为“高水位标记”)。当队列已满时,ZeroMQ会根据用户正在执行的消息传递的类型(所谓的“模式”)自动阻止发件人或丢弃消息。它使用户的应用程序可以通过任意传输相互通信:TCP,多播,进程内,进程间。用户无需更改代码即可使用其他传输方式。它使用依赖于消息传递模式的不同策略来安全地处理慢速/阻塞阅读器。它使用户可以使用各种模式来路由消息,例如请求-答复和发布-订阅。这些模式是创建拓扑和网络结构的方式。它使用户可以创建代理以通过单个呼叫将消息排队,转发或捕获。代理可以降低网络的互连复杂性。它使用网络上的简单帧来准确地传递完整的消息。如果用户写10k消息您将收到10k消息。它不对邮件强加任何格式。它们是从零到千兆字节的斑点。当用户要表示数据时,可以选择其他一些产品,例如msgpack,Google的协议缓冲区等。通过在有意义的情况下自动重试,它可以智能地处理网络错误。它减少了用户的碳足迹。用更少的CPU做更多的事情意味着用户的盒子会耗更少的功率,并且用户可以使旧盒子的使用时间更长。
实际上,ZeroMQ的作用远不止于此。它对用户开发具有网络功能的应用程序的方式具有颠覆性影响。从表面上看,这是一个受套接字启发的API,用户可以在上面执行zmq_recv()和zmq_send()。但是消息处理迅速成为中心循环,用户的应用程序很快分解为一组消息处理任务。优雅自然。它可以扩展:每个任务都映射到一个节点,并且这些节点通过任意传输相互通信。一个进程中的两个节点(节点是一个线程),一个盒子中的两个节点(节点是一个进程)或一个网络上的两个节点(节点是一个盒子)都是一样的,没有更改应用程序代码。
2.ZMQ是什么
2.1 套接字(socket)是什么?
在介绍ZMQ之前,需要先简单介绍一下套接字(对应的英文为Socket)。
套接字起源于20世纪70年代加州大学伯克利分校版本的Unix,即人们所说的BSD Unix。因此,有时人们也把套接字称为“伯克利套接字”或“BSD套接字”。一开始,套接字被设计用在同一台主机上多个应用程序之间的通讯。这也被称作进程间通讯,或IPC。
套接字是用来做什么并且怎样工作的呢?
应用层通过传输层进行数据通信时,TCP和UDP会遇到同时为多个应用程序进程提供并发服务的问题。多个TCP连接或多个应用程序进程可能需要通过同一个TCP协议端口传输数据。为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与TCP/IP协议交互提供了称为套接字(Socket)的接口,区分不同应用程序进程间的网络通信和连接。
网络化的应用程序在开始任何通讯之前都必需要创建套接字。就像电话的插口一样,没有它就完全没办法通信。
生成套接字,主要有3个参数:通信的目的IP地址、使用的传输层协议(TCP或UDP)和使用的端口号。Socket原意是“插座”。通过将这3个参数结合起来,与一个“插座”Socket绑定,应用层就可以和传输层通过套接字接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。
Socket可以看成在两个程序进行通讯连接中的一个端点,一个程序将一段信息写入Socket中,该Socket将这段信息发送给另外一个Socket中,使这段信息能传送到其他程序中。
2.2 ZMQ是什么?
那ZMQ和Socket有什么关联呢?
阅读了ZMQ的Guide文档后,我的理解是,ZMQ是个类似于Socket的一系列接口,他跟Socket的区别是:普通的socket是端到端的(1:1的关系),而ZMQ却是可以N:M 的关系,人们对BSD套接字的了解较多的是点对点的连接,点对点连接需要显式地建立连接、销毁连接、选择协议(TCP/UDP)和处理错误等,而ZMQ屏蔽了这些细节,让你的网络编程更为简单。ZMQ用于node与node间的通信,node可以是主机或者是进程。
2.2 TCP和UDP是什么?
在这里还需简单介绍一下上文中的通信协议TCP和UDP。
首先说下tcp/ip协议的作用,网络刚出来的时候,一片混乱,那要传输数据就得大家都遵守一个规则,大家都按照这个,然后就出现了tcp/ip协议。也许你听过3次握手,4次断开,说的就是tcp/ip连接的一个过程。加入a计算机要和b计算机通信,过程是这样的
a:在吗,我可以连你吗
b:在,你连吧
a:好的,我要给你发数据了
这就是3次握手,这就建立好通道了,两台计算机就可以进行通信了。那么4次断开是什么呢?
a:我要和你断开了
b:好的,你断开吧
b:关闭通道
a:关闭通道
为什么关闭2次呢,因为两端要互相传数据,挖了两条路,一条路用来b给a传数据,另外一条是a给b传数据,所以是2次关闭,各自关闭各自的通道。这两条路呢,就有个词语叫全双工,就是两边都可以互相发送数据,如果只有一端可以发送数据,那就叫单工。
而udp协议就比较简单了,没有那么复杂的断开和连接,不需要3次握手,不需要确定客户端、服务端是否能收到,tcp/ip是必须建立好连接之后,才能发数据,而udp是无连接的,知道ip和端口号直接就是发,它比tcp/ip快,但是不安全。
upd就像写信一样,有可能在路上就没有了,对方没有收到。而tcp/ip就像打电话一样,必须得接通才能说话。
使用UDP协议时,不需要建立连接,只需要知道对方的IP地址和端口号,就可以直接发数据包。但是,能不能到达就不知道了。
虽然用UDP传输数据不可靠,但它的优点是和TCP比,速度快,对于不要求可靠到达的数据,就可以使用UDP协议。
3.ZMQ的三种通信模式
3.1 应答模式(Request-Reply)
请求端发送一个简单的 hello,服务端则回应一个 world。请求端和服务端都可以是 1:N 的模型。通常把 1 认为是 Server ,N 认为是 Client 。
注意:使用REQ-REP套接字发送和接受消息是需要遵循一定规律的。客户端首先使用zmq_send()发送消息,再用zmq_recv()接收,如此循环。如果打乱了这个顺序(如连续发送两次)则会报错。类似地,服务端必须先进行接收,后进行发送。
3.2 订阅发布模式(Publisher-Subscriber)
我们可以想象一下天气预报的订阅模式,由一个节点提供信息源,由其他的节点,接受信息源的信息。
注意:PUB-SUB套接字组合是异步的。客户端在一个循环体中使用recv ()接收消息,如果向SUB套接字发送消息则会报错;类似地,服务端可以不断地使用send ()发送消息,但不能再PUB套接字上使用recv ()。
关于PUB-SUB套接字,还有一点需要注意:你无法得知SUB是何时开始接收消息的。就算你先打开了SUB套接字,后打开PUB发送消息,这时SUB还是会丢失一些消息的,因为建立连接是需要一些时间的。很少,但并不是零。解决此问题需要在PUB端加入sleep。
3.3 管道模式(Parallel Pipeline)
想象一下这样的场景,如果需要统计各个机器的日志,我们需要将统计任务分发到各个节点机器上,最后收集统计结果,做一个汇总。PipeLine 比较适合于这种场景。该模式结构如下图所示,由三部分组成,其中push进行数据推送,work进行数据缓存,pull进行数据竞争获取处理。区别于Publish-Subscribe存在一个数据缓存和处理负载。
当连接被断开,数据不会丢失,重连后数据继续发送到对端。
Task ventilator 使用的是 SOCKET_PUSH,将任务分发到 Worker 节点上。而 Worker 节点上,使用 SOCKET_PULL 从上游接受任务,并使用 SOCKET_PUSH 将结果汇集到 Slink。值得注意的是,任务的分发的时候也同样有一个负载均衡的路由功能,worker 可以随时自由加入,task ventilator 可以均衡将任务分发出去。
最后
以上就是忧虑钢笔为你收集整理的网络通讯协议图2020_ZeroMQ通信协议的学习与研究 邹鹏程 2019.10.13的全部内容,希望文章能够帮你解决网络通讯协议图2020_ZeroMQ通信协议的学习与研究 邹鹏程 2019.10.13所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复