saltstack系列(二)——zmq应答模式

python zeromq介绍

  1、ZeroMQ并不是一个对socket的封装,不能用它去实现已有的网络协议。

  2、有自己的模式,不同于更底层的点对点通讯模式。

  3、有比tcp协议更高一级的协议(当然ZeroMQ不一定基于TCP协议,它也可以用于进程间和进程内通讯)。

  4、改变了通讯都基于一对一的连接这个假设。

zeromq通讯模型

  1、请求应答模型

  由请求端发起请求,并等待回应端回应请求。从请求端来看,一定是一对对收发配对的;反之,在回应端一定是发收对。请求端和回应端都可以是1:N的模型。通常把1认为是server,N认为是Client。0MQ可以很好的支持路由功能(实现路由功能的组件叫做Device),把1:N扩展为N:M(只需要加入若干路由节点)。从这个模型看,更底层的端点地址是对上层隐藏的。每个请求都隐含回应地址,而应用则不关心它。

  2、发布订阅模型

  这个模型里,发布端是单向只发送数据的,且不关心是否把全部的信息都发送给订阅者。如果发布端开始发布信息的时候,订阅端尚未连接上,这些信息直接丢弃。不过一旦订阅连接上来,中间会保证没有信息丢失。同样,订阅端则只负责接收,而不能反馈。如果发布端和订阅端需要交互(比如要确认订阅者是否已经连接上),则使用额外的socket采用请求回应模型满足这个需求。

  3、管道模型

  这个模型里,管道是单向的,从PUSH端单向的向PULL端单向的推送数据流。

zeromq请求应答模型

  应答模式,就是一问一答,规则有这么几条:

   1、 必须先提问,后回答

2、 对于一个提问,只能回答一次

3、 在没有收到回答前不能再次提问

上代码,服务端: 

#coding=utf-8  

import zmq
import time  

context = zmq.Context()
socket = context.socket(zmq.REP)
socket.bind(‘tcp://127.0.0.1:8000‘)  

while True:
    message = socket.recv()
    print ‘received request: ‘ ,message  

    time.sleep(1)
    socket.send(‘World‘)

客户端:

#coding=utf-8
‘‘‘‘‘
你无法连续向服务器发送数据,必须发送一次,接收一次
REQ和REP模式中,客户端必须先发起请求 

‘‘‘
import zmq  

context = zmq.Context()
print ‘connect to hello world server‘
socket =  context.socket(zmq.REQ)
socket.connect(‘tcp://127.0.0.1:8000‘)  

for request in range(1,10):
    print ‘send ‘,request,‘...‘
    socket.send(‘hello‘)
    message = socket.recv()
    print ‘received reply ‘,request,‘[‘,message,‘]‘

说明:

  客户端总是必须先提问,客户端提问后,必须等待回答,在收到回答前如果又发出提问,那么会报错。  

  zmq.REP是应答方,zmq.REQ是提问方,显然,我们可以有多个提问方,但只能有一个提问方。

问答环节

问题1:应答方和提问方谁先启动呢?(服务端和客户端谁先启动呢?)

答:谁先启动都可以,和pub/sub模式一样

问题2:如果服务端断掉或者客户端断掉会产生怎样的影响?

答:如果是客户端断掉,对服务端没有任何影响,如果客户端随后又重新启动,那么两方继续一问一答,但是如果是服务端断掉了,就可能会产生一些问题,这要看服务端是在什么情况下断掉的,如果服务端是在回答完问题后断掉的,那么没影响,重启服务端后,双发继续一问一答,但如果服务端是在收到问题后断掉了,还没来得及回答问题,这就有问题了,那个提问的客户端迟迟得不到答案,就会一直等待答案,因此不会再发送新的提问,服务端重启后,客户端迟迟不发问题,所以也就一直等待提问。

问题3: 看代码,服务端根本就没去区分提问者是谁,如果有两个提问题的人,如何保证服务端的答案准确的发给那个提问的客户端呢?

答:关于这一点,大家不必担心,zmq的内部机制已经做了保证,提问者必然只收到属于自己的答案,我们不必去操心zmq是怎么做到的,你只需关于业务本身即可。

现在,我们把服务端代码做修改

#coding=utf-8  

import zmq
import time  

context = zmq.Context()
socket = context.socket(zmq.REP)
socket.bind(‘tcp://127.0.0.1:8000‘)  

while True:
    message = socket.recv()
    print ‘received request: ‘ ,message
    time.sleep(1)
    if message == ‘hello‘:
        socket.send(‘World‘)
    else:
        socket.send(‘success‘)  

服务端

#coding=utf-8  

import zmq  

context = zmq.Context()
print ‘connect to hello world server‘
socket =  context.socket(zmq.REQ)
socket.connect(‘tcp://127.0.0.1:8000‘)  

for request in range(1,10):
    print ‘send ‘,request,‘...‘
    socket.send(‘hello‘)
    message = socket.recv()
    print ‘received reply ‘,request,‘[‘,message,‘]‘  

客户端1

#coding=utf-8  

import zmq  

context = zmq.Context()
print ‘connect to hello world server‘
socket =  context.socket(zmq.REQ)
socket.connect(‘tcp://127.0.0.1:8000‘)  

for request in range(1,10):
    print ‘send ‘,request,‘...‘
    socket.send(‘ok‘)
    message = socket.recv()
    print ‘received reply ‘,request,‘[‘,message,‘]‘  

客户端2

实际的运行结果如图:

不难看出,每个客户端都收到了只属于自己的答案

时间: 2024-11-05 21:55:29

saltstack系列(二)——zmq应答模式的相关文章

Java设计模式菜鸟系列(二十三)访问者模式建模与实现

转载请注明出处:http://blog.csdn.net/lhy_ycu/article/details/40028509 访问者模式(Visitor):把数据结构和作用于结构上的操作解耦合,使得操作集合可相对自由地演化.访问者模式适用于数据结构相对稳定而算法又容易变化的系统.访问者模式的优点是增加操作很容易,因为增加操作意味着增加新的访问者:而它的缺点就是增加新的数据结构很困难. 一.uml建模: 二.代码实现 /** * 访问者模式(Visitor):把数据结构和作用于结构上的操作解耦合,使

Java设计模式菜鸟系列(二十)解释器模式建模与实现

转载请注明出处:http://blog.csdn.net/lhy_ycu/article/details/40019829 解释器模式(Interpreter):它定义了对象与对象之间进行某种操作之后会得到什么值.一般主要应用在OOP开发中的编译器的开发中,所以适用面比较窄. 一.uml建模: 二.代码实现 /** * 解释器模式(Interpreter):它定义了对象与对象之间进行某种操作之后会得到什么值. * * 一般主要应用在OOP开发中的编译器的开发中,所以适用面比较窄. * * 示例:

设计模式系列二(策略者模式)

浑浑噩噩的过的漫无目的,更多的是迷茫,真不知该如何定位自己的人生?空有远大抱负,而又力不从心!有句话说的好,当你的才能撑不起你的野心的时候,就该静下来心来好好学习了!于是闲来无事,便继续开始我的设计模式之游!今天便研究下策略者模式! 1.策略者模式解析 大话设计模式是这样讲道: 策略者模式是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有的算法减少各种算法类与使用算法类之间的耦合[DPE]. 个人理解:所谓一系列算法方法就是一系列

Saltstack系列之二——Targeting

昨天原本打算是写salt的WebUi-halite的,不过想了想,还是先写一些"看得见.摸得着的"的一些显而易见,最基本的用处吧.(尝到一些甜头后,才会继续去钻研吧...哈哈~) 那,什么是Targeting呢? 官方给到的解释是: Specifying which minions should run a command or execute a state by matching against hostnames, or system information, or define

自动化运维Saltstack系列(一)之基础功能篇

Saltstack简介  Saltstack是基于Python开发的一套C/S架构,具备Puppet.Ansible功能于一身的配置管理工具,功能十分强大,各模块融合度及复用性极高:使用号称世界上最快的消息队列ZeroMQ使得Saltstack能够秒级在数万台服务器上进行各种操作,而且使用RAS Key方式确认身份,传输采用AES加密,安全性能更高: Saltstack不仅仅是一款配置管理工具,还是一款做云计算和数据中心架构编排利器.目前Salt-cloud项目也已经合并到Saltstack主项

Saltstack系列之一——安装篇

最近,和暴雪中国区带技术的一个人聊了不少,他们在测试salt,不过目前用的是puppet,服务器数量也快要1000多台.那为什么他们会去考虑测试salt.另谋他法呢,肯定是有salt一定优势的. 其实我对puppet的名声早已经耳濡目染了1年多了,虽然还没去研究过....也知道有同类开源产品saltstack的存在.不过,puppet是由ruby写的,saltstack则是由python编写的,综合下来就选择了研究salt. 国内的博客真是各种抄袭.各种搬啊...真找不到几篇有用的文档和资料.还

原始套接字基础(原始套接字系列二)

在进入Raw Socket多种强大的应用之前,我们先讲解怎样建立一个Raw Socket及怎样用建立的Raw Socket发送和接收IP包. 建立Raw Socket 在Windows平台上,为了使用Raw Socket,需先初始化WINSOCK: // 启动 WinsockWSAData wsaData;if (WSAStartup(MAKEWORD(2, 1), &wsaData) != 0){ cerr << "Failed to find Winsock 2.1 or

C# 玩转计算机系列(二)-操作IIS服务

之前由于工作需要自己做一个一键部署的小工具,实现三个模块的功能:TFS操作创建映射并获取最新源代码:SQL Server数据库注册表配置数据库连接:IIS站点部署,生成可访问的IIS站点.由于是基于自己的工作环境下的开发,所以在TFS和SQL Server配置工具化实现,有一些点是默认按照公司的环境配置参数默认的,虽然不是广泛适用每一种情况的环境部署,但是在学习这三个模块的开发过程中,还是有很多东西是可以值得分享的. 今天先分享一下,如何通过工具化实现IIS站点部署和配置,为了可复用性,IIS操

Exchange Server 2013系列二:服务器角色

杜飞 在上一篇文章中,我们提到现在硬件性能的增加以及成本的下降,硬件已经不再成为软件应用的约束因素,特别是CPU,其 计算能力的成本显著降低.Exchange 2013 的主要设计目标是简化缩放.提高硬件利用率和实现故障隔离.Exchange 2013一开始将服务器角色的数目减少到了两个:客户端访问服务器角色和邮箱服务器角色,当然,升级到SP1之后也包含边缘服务器角色或者是边界网络中安装 Exchange 2007 或 Exchange 2010 边缘传输服务器角色.如下图所示: 客户端访问服务