Python网络编程之ZeroMQ知识总结


Posted in Python onApril 25, 2021

一、ZeroMQ概述

  •  ZeroMQ(又名ØMQ,MQ,或zmq)像一个可嵌入的网络库,但其作用就像一个并发框架。
  • ZeroMQ类似于标准Berkeley套接字,其提供了各种传输工具,如进程内、进程间、TCP和组播中进行原子消息传送的套接字
  • 可以使用各种模式实现N对N的套接字连接,这些模式包括:发布-订阅、任务分配、请求-应答。
  • ZeroMQ的速度足够快,因此可充当集群产品的结构。
  • ZeroMQ的异步I/O模型提供了可扩展的多核应用程序,用异步消息来处理任务
  • ZeroMQ核心由C语言编写,支持C、C++、java、python等多种编程语言的API,并可运行在大多数操作系统上

总结以下:ØMQ (ZeroMQ) 是一个基于消息队列的多线程网络库,它封装了网络通信、消息队列、线程调度等功能,向上层提供简洁的API,应用程序通过加载库文件,调用API函数来实现高性能网络通信。

看起来有些抽象,下面我们结合ZeroMQ 的 Python 封装———— pyzmp,用实例看一下ZeroMQ的三种最基本的工作模式。

二、安装

安装方法

pip install pyzmq

查看是否安装成功

>>> import zmq
>>> print(zmq.__version__)
22.0.3

三、Request-Reply (请求响应模式)

3.1 Request-Reply模式概述:

  • 消息双向的,有来有往。
  • Client请求的消息,Server必须答复给Client。
  • Client在请求后,Server必须回响应,注意:Server不返回响应会报错。
  • Server和Client都可以是1:N的模型。通常把1认为是Server,N认为是Client。
  • 更底层的端点地址是对上层隐藏的,每个请求都隐含回应地址,而应用则不关心它。
  • ZMQ 可以很好的支持路由功能(实现路由功能的组件叫做 Device),把 1:N 扩展为 N:M(只需要加入若干路由节点)。

Python网络编程之ZeroMQ知识总结

3.2 Client端python实现

#client.py

import zmq

context = zmq.Context()

#  Socket to talk to server
print("Connecting to hello world server…")
socket = context.socket(zmq.REQ)
socket.connect("tcp://localhost:5555")
socket.send(b"Hello")
#  Get the reply.
message = socket.recv()
print(f"Received reply [ {message} ]")

3.3 Server端python实现

#server.py
import time
import zmq

context = zmq.Context()
socket = context.socket(zmq.REP)
socket.bind("tcp://*:5555")

while True:
    #  Wait for next request from client
    message = socket.recv()
    print("Received request: %s" % message)

    #  Do some 'work'
    time.sleep(1)

    #  Send reply back to client
    socket.send(b"World")
  • 启动client.py 首先会打印Connecting to hello world server… 但不会受到任何消息。
  • 然后启动server.py ,客户端收到来自客户端的request: b'Hello'
  • 此时client端收到来自server端的 reply: [ b'World' ]
python client.py 
Connecting to hello world server…
Received reply [ b'World' ]
python server.py 
Received request: b'Hello'

可以试一下,多运行几个client.py,看看情况是什么样的。

Python网络编程之ZeroMQ知识总结

四、Publish/Subscribe(订阅-发布模式 )

4.1 Pub-Subs模式概述:

  • 消息单向,有去无回
  • 一个发布端,多个订阅端;发布端只管产生数据,发布端发布一条消息,可被多个订阅端同时收到。
  • 发布者不必关心订阅者的加入和离开,消息会以 1:N 的方式扩散到每个订阅者。
  • 广播所有client,没有队列缓存,断开连接数据将永远丢失。
  • 如果Publish端开始发布信息时,Subscribe端尚未连接进来,则这些信息会被直接丢弃。
  • PUB和SUB谁bind谁connect并无严格要求(虽本质并无区别),但仍建议PUB使用bind,SUB使用connect
  • 使用SUB设置一个订阅时,必须使用zmq_setsockopt()对消息进行过滤

Python网络编程之ZeroMQ知识总结

这里直接引用官方文档的例子:

发布者:类似于一个天气更新服务器,向订阅者发送天气更新,内容包括邮政编码、温度、湿度等信息

#Publisher.py
import zmq
from random import randrange


context = zmq.Context()
socket = context.socket(zmq.PUB)
socket.bind("tcp://*:5556")

while True:
    zipcode = randrange(1, 100000)
    temperature = randrange(-80, 135)
    relhumidity = randrange(10, 60)

    socket.send_string("%i %i %i" % (zipcode, temperature, relhumidity))

订阅者:它监听发布者更新的数据流,过滤只接收与特定邮政编码相关的天气信息,默认接收接收10条数据

#Subscribe.py 
import sys
import zmq


#  Socket to talk to server
context = zmq.Context()
socket = context.socket(zmq.SUB)

print("Collecting updates from weather server...")
socket.connect("tcp://localhost:5556")

# Subscribe to zipcode, default is NYC, 10001
zip_filter = sys.argv[1] if len(sys.argv) > 1 else "10001"

# Python 2 - ascii bytes to unicode str
if isinstance(zip_filter, bytes):
    zip_filter = zip_filter.decode('ascii')
socket.setsockopt_string(zmq.SUBSCRIBE, zip_filter)

# Process 5 updates
total_temp = 0
for update_nbr in range(5):
    string = socket.recv_string()
    zipcode, temperature, relhumidity = string.split()
    total_temp += int(temperature)

print(
    "Average temperature for zipcode '%s' was %dF"
    % (zip_filter, total_temp / (update_nbr + 1))
)

Python网络编程之ZeroMQ知识总结

五、Push/Pull(流水线模式)

5.1 流水线模式概述:

  • 主要用于多任务并行。
  • 消息单向,有去无回。
  • Push的任何一个消息,始终只会有一个Pull端收到消息。
  • Push 端还是 Pull 端都可以做 server,bind 到某个地址等待对方访问。
  • 如果有多个PULL端同时连接到PUSH端,则PUSH端会在内部做一个负载均衡,采用平均分配的算法,将所有消息均衡发布到PULL端上。
  • 由三部分组成,Push进行数据推送,work进行数据缓存,Pull进行数据竞争获取处理。
  • 存在一个数据缓存和处理负载,当连接被断开,数据不会丢失,重连后数据继续发送到对端。

Python网络编程之ZeroMQ知识总结

ventilator 使用的是 SOCKET_PUSH,将任务分发到 Worker 节点上。Worker 节点上,使用 SOCKET_PULL 从上游接受任务,并使用 SOCKET_PUSH 将结果汇集到 Sink。值得注意的是,任务的分发的时候也同样有一个负载均衡的路由功能,worker 可以随时自由加入,ventilator 可以均衡将任务分发出去。

Push/Pull模式还是蛮常用的,这里我们主要测试一下它的负载均衡。

5.2 Ventilator

# ventilator.py
import zmq
import time

context = zmq.Context()
socket = context.socket(zmq.PUSH)
socket.bind("tcp://*:5557")

while True:
    socket.send(b"test")
    print("已发送")
    time.sleep(1)

5.3 worker

# worker.py
import zmq

context = zmq.Context()

recive = context.socket(zmq.PULL)
recive.connect('tcp://127.0.0.1:5557')

sender = context.socket(zmq.PUSH)
sender.connect('tcp://127.0.0.1:5558')

while True:
    data = recive.recv()
    print("work1 正在转发...")
    sender.send(data)

5.4 sink

# sink.py
import zmq
import sys

context = zmq.Context()
socket = context.socket(zmq.PULL)
socket.bind("tcp://*:5558")

while True:
    response = socket.recv()
    print("response: %s" % response)

打开4个Terminal,分别运行

python sink.py
python worker.py
python worker.py
python ventilator.py

Python网络编程之ZeroMQ知识总结

六、总结

消息模型可以根据需要组合使用,后续的代理模式和路由模式等都是在三种基本模式上面的扩展或变异。

到此这篇关于Python网络编程之ZeroMQ知识总结的文章就介绍到这了,更多相关Python ZeroMQ知识总结内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python3.0 字典key排序
Dec 24 Python
Python3基础之基本运算符概述
Aug 13 Python
Python查找函数f(x)=0根的解决方法
May 07 Python
Python实现MySQL操作的方法小结【安装,连接,增删改查等】
Jul 12 Python
pycharm远程调试openstack代码
Nov 21 Python
python2和python3的输入和输出区别介绍
Nov 20 Python
Python Django view 两种return的实现方式
Mar 16 Python
Python实现清理微信僵尸粉功能示例【基于itchat模块】
May 29 Python
新手学python应该下哪个版本
Jun 11 Python
虚拟机下载python是否需要联网
Jul 27 Python
解决python绘图使用subplots出现标题重叠的问题
Apr 30 Python
python基础之文件处理知识总结
May 23 Python
Python 文本滚动播放器的实现代码
Apr 25 #Python
Python基于Opencv识别两张相似图片
matplotlib之pyplot模块实现添加子图subplot的使用
python实现简单区块链结构
python实现图片九宫格分割的示例
详解python中[-1]、[:-1]、[::-1]、[n::-1]使用方法
Apr 25 #Python
浅谈Python项目的服务器部署
Apr 25 #Python
You might like
简单的方法让你的后台登录更加安全(php中加session验证)
2012/08/22 PHP
Laravel框架在本地虚拟机快速安装的方法详解
2018/06/11 PHP
js下利用控制器载入对应脚本
2010/07/17 Javascript
淘宝搜索框效果实现分析
2011/03/05 Javascript
script的async属性以非阻塞的模式加载脚本
2013/01/15 Javascript
js中onload与onunload的使用示例
2013/08/25 Javascript
jQuery实现长按按钮触发事件的方法
2015/02/02 Javascript
JS设置网页图片vspace和hspace属性的方法
2015/04/01 Javascript
jquery 中ajax执行的优先级
2015/06/22 Javascript
jquery实现的树形目录实例
2015/06/26 Javascript
JS获取input file绝对路径的方法(推荐)
2016/08/02 Javascript
详解Vue.js动态绑定class
2016/12/20 Javascript
javaScript生成支持中文带logo的二维码(jquery.qrcode.js)
2017/01/03 Javascript
JavaScript实现经纬度转换成地址功能
2017/03/28 Javascript
nodejs acl的用户权限管理详解
2018/03/14 NodeJs
基于jQuery实现挂号平台首页源码
2020/01/06 jQuery
JavaScript中变量提升和函数提升的详解
2020/08/07 Javascript
微信小程序完美解决scroll-view高度自适应问题的方法
2020/08/08 Javascript
vue 里面的 $forceUpdate() 强制实例重新渲染操作
2020/09/21 Javascript
Javascript执行上下文顺序的深入讲解
2020/11/04 Javascript
解决vue-cli输入命令vue ui没效果的问题
2020/11/17 Javascript
[56:29]Secret vs Optic 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
python冒泡排序算法的实现代码
2013/11/21 Python
使用Python的Supervisor进行进程监控以及自动启动
2014/05/29 Python
浅析Python中的多进程与多线程的使用
2015/04/07 Python
pandas全表查询定位某个值所在行列的方法
2018/04/12 Python
详解PyCharm配置Anaconda的艰难心路历程
2018/08/13 Python
关于Django ForeignKey 反向查询中filter和_set的效率对比详解
2018/12/15 Python
浅析Python 条件控制语句
2020/07/15 Python
Html5之webcoekt播放JPEG图片流
2020/09/22 HTML / CSS
西部世纪.net笔试题面试题
2014/04/03 面试题
毕业自我鉴定范文
2013/11/06 职场文书
生日派对邀请函
2014/01/13 职场文书
2014年统战工作总结
2014/12/09 职场文书
银行实习推荐信
2015/03/27 职场文书
Java死锁的排查
2022/05/11 Java/Android