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 相关文章推荐
Python过滤函数filter()使用自定义函数过滤序列实例
Aug 26 Python
浅谈Python基础之I/O模型
May 11 Python
利用python 更新ssh 远程代码 操作远程服务器的实现代码
Feb 08 Python
浅析PHP与Python进行数据交互
May 15 Python
Python基于分析Ajax请求实现抓取今日头条街拍图集功能示例
Jul 19 Python
Python 中Django安装和使用教程详解
Jul 03 Python
在Python中画图(基于Jupyter notebook的魔法函数)
Oct 28 Python
解决Python数据可视化中文部分显示方块问题
May 16 Python
python的help函数如何使用
Jun 11 Python
解决运行django程序出错问题 'str'object has no attribute'_meta'
Jul 15 Python
python 写一个文件分发小程序
Dec 05 Python
matplotlib绘制正余弦曲线图的实现
Feb 22 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文件去掉PHP注释空格的函数分析(PHP代码压缩)
2013/07/02 PHP
PHP mongodb操作类定义与用法示例【适合mongodb2.x和mongodb3.x】
2018/06/16 PHP
PHP正则验证字符串是否为数字的两种方法并附常用正则
2019/02/27 PHP
基于laravel-admin 后台 列表标签背景的使用方法
2019/10/03 PHP
jquery 打开窗口返回值实现代码
2010/03/04 Javascript
能说明你的Javascript技术很烂的五个原因分析
2011/10/28 Javascript
table insertRow、deleteRow定义和用法总结
2014/05/14 Javascript
使用Node.js实现一个简单的FastCGI服务器实例
2014/06/09 Javascript
深入理解事件冒泡(Bubble)和事件捕捉(capture)
2016/05/28 Javascript
浅析JS获取url中的参数实例代码
2016/06/14 Javascript
JavaScript运动框架 多物体任意值运动(三)
2017/05/17 Javascript
基于jQuery封装的分页组件
2017/06/26 jQuery
JsChart组件使用详解
2018/03/04 Javascript
Vue路由切换时的左滑和右滑效果示例
2018/05/29 Javascript
从零开始学习搭建React脚手架项目
2018/08/23 Javascript
vue项目在安卓低版本机显示空白的原因分析(两种)
2018/09/04 Javascript
Vue-Quill-Editor富文本编辑器的使用教程
2018/09/21 Javascript
vue项目中自定义video视频控制条的实现代码
2020/04/26 Javascript
js获取图片的base64编码并压缩
2020/12/05 Javascript
Python3实现抓取javascript动态生成的html网页功能示例
2017/08/22 Python
pandas 透视表中文字段排序方法
2018/11/16 Python
Python实现繁?转为简体的方法示例
2018/12/18 Python
python读取目录下最新的文件夹方法
2018/12/24 Python
Python爬虫抓取论坛关键字过程解析
2020/10/19 Python
PyCharm最新激活码(2020/10/27全网最新)
2020/10/27 Python
Tarte Cosmetics官网:美国最受欢迎的化妆品公司之一
2017/08/24 全球购物
HTC VIVE美国官网:VR虚拟现实眼镜
2018/02/13 全球购物
VisionPros美国站:加拿大在线隐形眼镜和眼镜零售商
2020/02/11 全球购物
FirstCry阿联酋儿童和婴儿产品网上购物:FirstCry.ae
2021/02/22 全球购物
晚宴邀请函范文
2014/01/15 职场文书
2014年标准化工作总结
2014/12/17 职场文书
奖学金感谢信
2015/01/21 职场文书
升学宴来宾致辞
2015/07/27 职场文书
留学文书中的个人陈述,应该注意哪些问题?
2019/08/23 职场文书
SSM VUE Axios详解
2021/10/05 Vue.js
html5调用摄像头截图功能
2022/01/18 Javascript