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 中 Meta Classes详解
Feb 13 Python
用python与文件进行交互的方法
Mar 01 Python
Python OpenCV处理图像之图像直方图和反向投影
Jul 10 Python
Python中asyncio与aiohttp入门教程
Oct 16 Python
Python字典中的键映射多个值的方法(列表或者集合)
Oct 17 Python
python将.ppm格式图片转换成.jpg格式文件的方法
Oct 27 Python
Django开发的简易留言板案例详解
Dec 04 Python
详解PyCharm安装MicroPython插件的教程
Jun 24 Python
python使用writerows写csv文件产生多余空行的处理方法
Aug 01 Python
pytorch torchvision.ImageFolder的用法介绍
Feb 20 Python
Pytorch高阶OP操作where,gather原理
Apr 30 Python
Python 读取位于包中的数据文件
Aug 07 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 正则表达式之正则处理函数小结(preg_match,preg_match_all,preg_replace,preg_split)
2012/10/05 PHP
修改Laravel5.3中的路由文件与路径
2016/08/10 PHP
PHP中explode函数和split函数的区别小结
2016/08/24 PHP
PHP策略模式定义与用法示例
2017/07/27 PHP
通过身份证号得到出生日期和性别的js代码
2009/11/23 Javascript
javascript简单实现表格行间隔显示颜色并高亮显示
2013/11/29 Javascript
NodeJS中利用Promise来封装异步函数
2015/02/25 NodeJs
jQuery实现的支持IE的html滑动条
2015/03/16 Javascript
JavaScript对Cookie进行读写操作实例
2015/07/25 Javascript
js实现文字闪烁特效的方法
2015/12/17 Javascript
JS获得一个对象的所有属性和方法实例
2017/02/21 Javascript
AngularJS 购物车全选/取消全选功能的实现方法
2017/08/14 Javascript
nodejs用gulp管理前端文件方法
2018/06/24 NodeJs
layui获取选中行数据的实例讲解
2018/08/19 Javascript
js prototype深入理解及应用实例分析
2019/11/25 Javascript
[33:28]完美世界DOTA2联赛PWL S3 PXG vs GXR 第三场 12.19
2020/12/24 DOTA
详细探究Python中的字典容器
2015/04/14 Python
Python cookbook(数据结构与算法)对切片命名清除索引的方法
2018/03/13 Python
Python实现 PS 图像调整中的亮度调整
2019/06/28 Python
python获取引用对象的个数方式
2019/12/20 Python
Python日志打印里logging.getLogger源码分析详解
2021/01/17 Python
css3针对移动端卡顿问题的解决(动画性能优化)
2020/02/14 HTML / CSS
关于iframe跨域使用postMessage的实现
2019/10/29 HTML / CSS
美国著名的户外用品品牌:L.L.Bean
2018/01/05 全球购物
美国五金商店:Ace Hardware
2018/03/27 全球购物
AOP的定义以及作用
2013/09/08 面试题
Linux管理员面试经常问道的相关命令
2014/12/12 面试题
关于毕业的中学校园广播稿
2014/01/26 职场文书
辅导员评语
2014/05/04 职场文书
班主任与学生安全责任书
2014/07/25 职场文书
质监局领导班子践行群众路线整改方案
2014/10/26 职场文书
圆明园观后感
2015/06/03 职场文书
于丹论语心得观后感
2015/06/15 职场文书
教师法制教育培训学习心得体会
2016/01/14 职场文书
幽默导游词应该怎么写?
2019/08/26 职场文书
人物搭配车车超萌联名预备中 【咒术迴战】 ⨯ 【天竺鼠车车】 展开合作
2022/04/11 日漫