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 随机生成中文验证码的实例代码
Mar 20 Python
举例讲解如何在Python编程中进行迭代和遍历
Jan 19 Python
Python中functools模块函数解析
Mar 12 Python
关于python pyqt5安装失败问题的解决方法
Aug 08 Python
python 实现生成均匀分布的点
Dec 05 Python
基于Python和PyYAML读取yaml配置文件数据
Jan 13 Python
python 连续不等式语法糖实例
Apr 15 Python
python接入支付宝的实例操作
Jul 20 Python
Python Matplotlib绘图基础知识代码解析
Aug 31 Python
python实现双人五子棋(终端版)
Dec 30 Python
解决pip安装tensorflow中出现的no module named tensorflow.python 问题方法
Feb 20 Python
Pytorch反向传播中的细节-计算梯度时的默认累加操作
Jun 05 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获取客户端IP及URL的方法示例
2017/02/03 PHP
javascript 的Document属性和方法集合
2010/01/25 Javascript
jquery中event对象属性与方法小结
2013/12/18 Javascript
js中继承的几种用法总结(apply,call,prototype)
2013/12/26 Javascript
window.open()详解及浏览器兼容性问题示例探讨
2014/05/29 Javascript
angularJS 中$scope方法使用指南
2015/02/09 Javascript
js淡入淡出焦点图幻灯片效果代码分享
2015/09/08 Javascript
JS设置下拉列表框当前所选值的方法
2015/12/22 Javascript
jquery模拟多级复选框效果的简单实例
2016/06/08 Javascript
WebSocket+node.js创建即时通信的Web聊天服务器
2016/08/08 Javascript
angular ngClick阻止冒泡使用默认行为的方法
2016/11/03 Javascript
Bootstrap基本布局实现方法详解
2016/11/25 Javascript
JavaScript Base64 作为文件上传的实例代码解析
2017/02/14 Javascript
使用json-server简单完成CRUD模拟后台数据的方法
2018/07/12 Javascript
在antd4.0中Form使用initialValue操作
2020/11/02 Javascript
Python中实现两个字典(dict)合并的方法
2014/09/23 Python
在arcgis使用python脚本进行字段计算时是如何解决中文问题的
2015/10/18 Python
Python通过DOM和SAX方式解析XML的应用实例分享
2015/11/16 Python
python snownlp情感分析简易demo(分享)
2017/06/04 Python
Python中的__slots__示例详解
2017/07/06 Python
python 删除列表里所有空格项的方法总结
2018/04/18 Python
python基础梳理(一)(推荐)
2019/04/06 Python
在python3中使用shuffle函数要注意的地方
2020/02/28 Python
python实时监控logstash日志代码
2020/04/27 Python
45个非常奇妙的CSS3 特性应用示例
2012/01/01 HTML / CSS
印尼太阳百货公司网站:Matahari
2018/02/04 全球购物
Whittard官方海外旗舰店:英国百年茶叶品牌
2018/02/22 全球购物
美国正版电视节目和电影在线观看:Hulu
2018/05/24 全球购物
杰夫·班克斯男士服装网上商店:Jeff Banks
2019/10/24 全球购物
英国知名小木屋定制网站:Tiger Sheds
2020/03/06 全球购物
销售内勤岗位职责
2014/04/15 职场文书
1000字打架检讨书
2014/11/03 职场文书
2014年优质护理服务工作总结
2014/11/14 职场文书
家电创业计划书
2019/08/05 职场文书
用Python简陋模拟n阶魔方
2021/04/17 Python
JavaScript中reduce()的用法
2022/05/11 Javascript