一、作业需求

1、可以对指定机器异步的执行多个命令

例子:
请输入操作指令>>>:run ipconfig --host 127.0.0.0
in the call     tack_id:[24869c59-bdc3-4cfc-9a00-313e257d9f58]     cmd:[ipconfig]      host:[127.0.0.0]

>请输入操作指令>>>:check_all
查看所有任务编号:
1     24869c59-bdc3-4cfc-9a00-313e257d9f58
2     f2d05df2-05b7-4059-93cc-de7c80aee5af

请输入操作指令>>>:check_task 24869c59-bdc3-4cfc-9a00-313e257d9f58
查看任务[24869c59-bdc3-4cfc-9a00-313e257d9f58]返回结果:
Windows IP 配置

以太网适配器 本地连接:

连接特定的 DNS 后缀 . . . . . . . :
   本地链接 IPv6 地址. . . . . . . . : fe80::cddb:da51:7e58:2515%11
   IPv4 地址 . . . . . . . . . . . . : 192.168.1.119

二、readme

一、作业需求:

1、可以对指定机器异步的执行多个命令

例子:
请输入操作指令>>>:run ipconfig --host 127.0.0.0
in the call tack_id:[24869c59-bdc3-4cfc-9a00-313e257d9f58] cmd:[ipconfig] host:[127.0.0.0] 请输入操作指令>>>:run dir --host 127.0.0.0
in the call tack_id:[f2d05df2-05b7-4059-93cc-de7c80aee5af] cmd:[dir] host:[127.0.0.0] >请输入操作指令>>>:check_all
查看所有任务编号:
1 24869c59-bdc3-4cfc-9a00-313e257d9f58
2 f2d05df2-05b7-4059-93cc-de7c80aee5af 请输入操作指令>>>:chedk_task 24869c59-bdc3-4cfc-9a00-313e257d9f58 请输入有效操作指令 请输入操作指令>>>:check_task 24869c59-bdc3-4cfc-9a00-313e257d9f58 注意,每执行一条命令,即立刻生成一个任务ID,不需等待结果返回,通过命令check_task TASK_ID来得到任务结果 二、博客地址:http://www.cnblogs.com/catepython/p/9051490.html 三、运行环境 操作系统:Win10 Python:3.6.4rcl Pycharm:2017.3.4 四 、具体实现
思路解析: 分析需求其实可以发现,输入命令为消费者,执行命令是生产者,参照RabbitMQ的官方文档rpc部分和课上的代码就可以了。 1. 使用RabbitMQ_RPC, Queen使用主机IP 2. 消费者输入命令,分割字段,获取run,check_task,check_task_all,host等信息,传给生产者。 3. 生产者执行命令处理windows/linux不同消息发送情况windows decode(‘gbk’) linux decode('utf-8'),返回结果。 4. 消费者将结果存成字典,查询结果后删除。 五、测试流程 1、在本次作业中处理了各种操作指令的异常处理 如:数组越界、使用check_task操作时无效任务ID处理 2、对用户输入的格式就行了正则 如:IP地址格式的判断 3、同时能对多个服务主机发送并接收相应的数据信息 六、备注
1、完成本次作业看了5遍视频,百度了所有大神们的心得代码,终于理清了整个RPC框架和原理

readme

三、流程图

四、目录结构图

五、核心代码

conf目录

#-*-coding:utf-8 -*-
# Author: D.Gray import os BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) LOCAL_HOST = ('localhost')

setting

core主逻辑目录

#-*-coding:utf-8 -*-
# Author: D.Gray import pika,uuid,time,re
from conf import setting class Producer(object):
def __init__(self):
self.connaction = pika.BlockingConnection(pika.ConnectionParameters(setting.LOCAL_HOST))
self.channel = self.connaction.channel()
self.result = self.channel.queue_declare(exclusive=True) #生产一个随机queue
self.callback_queue = self.result.method.queue
# 声明一个queue,一收到消息就调用on_response函数
self.channel.basic_consume(self.on_response,no_ack=True,queue=self.callback_queue) def on_response(self,ch,method,props,body):
'''
处理收到消息函数
:param ch:
:param method:
:param props:
:param body:
:return:
'''
if self.corr_id == props.correlation_id:
self.response = body def call(self,cmd,host):
'''
发送操作指令至服务端函数
:param cmd:
:param host:
:return:
'''
self.response = None
self.corr_id = str(uuid.uuid4()) #把操作指令发送给服务端,并把与服务端约定好一个随机queue一同传过去
self.channel.basic_publish(exchange='',routing_key=host,
properties=pika.BasicProperties(
reply_to=self.callback_queue, #与服务端约定好一个随机queue进行第二次数据交互
correlation_id = self.corr_id
),
body=str(cmd)
) while self.response is None:
self.connaction.process_data_events() #非阻塞版的start_consume
# print('no message...')
# time.sleep(1)
task_id = self.corr_id
res = self.response.decode()
tmp_dict[task_id] = res
print('in the call\t tack_id:[%s]\t cmd:[%s]\t host:[%s]'%(task_id,cmd,host))
return task_id,res def help():
'''
帮助函数
:return:
'''
meg = '''\033[32;1m
run "df -h" --hosts 127.0.0.1 192.168.84.66:执行操作命令格式
check_task 54385061-aa3a-400f-8a21-2be368e66493:查看某个任务id返回结果
check_all:查看所有任务编号
\033[0m'''
print(meg) def checkip(ip):
'''
正则判断参数是否是IP地址格式
:param ip: 需判断的字符串
:return:
'''
p = re.compile('^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$')
if p.match(ip):
return True
else:
return False def start(cmd):
''' :param cmd:
:return:
'''
#print('in the start:',cmd)
if cmd[0] == 'run':
if len(cmd) > 3:
hosts = cmd[3:]
for host in hosts:
if checkip(host) is True: #调用checkip方法来判断参数是否符合IP地址格式
try:
cmd_rpc.call(cmd[1],host) #把操作指令和ip 传给call()方法去解析
except Exception as e:
print('\033[31;1m有异常报错:\033[0m', e)
help()
else:
print('\033[31;1m请输入有效IP地址\033[0m')
help()
else:
print('\033[31;1m请正确输入有效指令')
help()
elif cmd[0] == 'help':
help()
elif cmd[0] == 'check_all':
if len(tmp_dict) == 0:
print('\033[31;1m暂无任务ID\033[0m')
else:
print('查看所有任务编号:')
for index,key in enumerate(tmp_dict.keys()):
print('%s\t %s'%(index+1,key))
elif cmd[0] == 'check_task':
try:
print('查看任务[%s]返回结果:%s'%(cmd[1],tmp_dict[cmd[1]]))
del tmp_dict[cmd[1]]
except IndexError as e:
print('\033[31;1m数组越界:\033[0m',e)
help()
except KeyError as e:
print('\033[31;1m无效任务ID:\033[0m',e)
else:
print('\033[31;1m请输入有效操作指令\033[0m') cmd_rpc = Producer()
tmp_dict = {}
while True:
cmd_input = input('请输入操作指令>>>:').strip().split()
if len(cmd_input) == 0:continue
else:
start(cmd_input)

客户端

#-*-coding:utf-8 -*-
# Author: D.Gray
import pika
import subprocess
import platform
connaction = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connaction.channel()
channel.queue_declare(queue='127.0.0.0') #设置一个队列与客户端首次交互 os_res = platform.system()
def command(cmd):
if os_res == 'Windows':
res = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
msg = res.stdout.read().decode('gbk')
if len(msg) == 0:
msg = res.stderr.read().decode('gbk')
#print(msg)
return msg else:
res = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
#print(res)
msg = res.stdout.read().decode()
if len(msg) == 0:
msg = res.stderr.read().decode()
return msg def on_response(ch,method,props,body):
'''
处理客户端传来消息的函数
:param ch:
:param method:
:param props:
:param body:
:return:
'''
cmd = body.decode()
#('收到客户端传来参数:[%s]'%cmd)
response = command(cmd) #调用command函数来解析函数 ch.basic_publish(exchange='',routing_key=props.reply_to, #把消息传到与客户端约定好的随机queue中
properties=pika.BasicProperties(correlation_id = props.correlation_id),
body = str(response)) ch.basic_ack(delivery_tag=method.delivery_tag) #手动确认消息有无被消费掉 #监听1270.0.0这个队列一收到客户端传来的消息就调用on_response处理消息
channel.basic_consume(on_response,queue='127.0.0.0')
print('等待客户端传来求值参数...')
channel.start_consuming()

服务端

老男孩Day12作业:RabbitMQ-RPC版主机管理程序的更多相关文章

  1. RabbitMQ-RPC版主机管理程序

    一.作业需求 1.可以对指定机器异步的执行多个命令 例子: 请输入操作指令>>>:run ipconfig --host 127.0.0.0 in the call     tack ...

  2. 老男孩Day11作业:selectors版socket

    一.作业需求: 使用SELECT或SELECTORS模块实现并发简单版FTP 允许多用户并发上传下载文件 二.readme 一.作业需求: 使用SELECT或SELECTORS模块实现并发简单版FTP ...

  3. python10作业思路及源码:类Fabric主机管理程序开发(仅供参考)

    类Fabric主机管理程序开发 一,作业要求 1, 运行程序列出主机组或者主机列表(已完成) 2,选择指定主机或主机组(已完成) 3,选择主机或主机组传送文件(上传/下载)(已完成) 4,充分使用多线 ...

  4. python作业类Fabric主机管理程序开发(第九周)

    作业需求: 1. 运行程序列出主机组或者主机列表 2. 选择指定主机或主机组 3. 选择让主机或者主机组执行命令或者向其传输文件(上传/下载) 4. 充分使用多线程或多进程 5. 不同主机的用户名密码 ...

  5. python第五十二天---第九周作业 类 Fabric 主机管理程序

    类 Fabric 主机管理程序开发:1. 运行程序列出主机组或者主机列表2. 选择指定主机或主机组3. 选择让主机或者主机组执行命令或者向其传输文件(上传/下载)4. 充分使用多线程或多进程5. 不同 ...

  6. 【python】-- RabbitMQ RPC模型

    RabbitMQ RPC模型 RPC(remote procedure call)模型说通俗一点就是客户端发一个请求给远程服务端,让它去执行,然后服务端端再把执行的结果再返回给客户端. 1.服务端 i ...

  7. python 学习分享-实战篇类 Fabric 主机管理程序开发

    # 类 Fabric 主机管理程序开发: # 1. 运行程序列出主机组或者主机列表 # 2. 选择指定主机或主机组 # 3. 选择让主机或者主机组执行命令或者向其传输文件(上传/下载) # 4. 充分 ...

  8. 类 Fabric 主机管理程序开发

    类 Fabric 主机管理程序开发:1. 运行程序列出主机组或者主机列表2. 选择指定主机或主机组3. 选择让主机或者主机组执行命令或者向其传输文件(上传/下载4. 充分使用多线程或多进程5. 不同主 ...

  9. 8.rabbitmq RPC模拟微服务架构中的服务调用

    标题 : 8.rabbitmq RPC模拟微服务架构中的服务调用 目录 : RabbitMQ 序号 : 8 { var connectionFactory = new ConnectionFactor ...

随机推荐

  1. 110. Balanced Binary Tree (Tree; DFS)

    Given a binary tree, determine if it is height-balanced. For this problem, a height-balanced binary ...

  2. ios 单个ViewController屏幕旋转

    如果需要旋转的ViewController 使用了UINavigationController,对UINavigationController进行如下扩展 @implementation UINavi ...

  3. C#中释放数据库连接资源

    1.确保释放数据库连接资源的两种方式如下:   a.使用try...catch...finally语句块,在finally块中关闭连接:   b.使用using语句块,无论如何退出,都会自动关闭连接: ...

  4. Golang之fmt格式“占位符”

    golang的fmt包实现了格式化I/O函数: package main import "fmt" type Human struct { Name string } func m ...

  5. 现在有很多第三方的SDK来做直播,那么我们改选择哪一种?

    现在大部分的都会借助第三方的直播技术,这样可以保证直播的质量,趣拍直播就很不错,SDK很好集成,芒果直播也在用.下面来分析一下趣拍直播的一些心得. 如何快速搭建一个完整的手机直播系统 在这个直播如火如 ...

  6. 与table有关的布局

    当IE8发布时,它将支持很多新的CSS display属性值,包括与表格相关的属性值:table.table-row和table-cell,它也是最后一款支持这些属性值的主流浏览器.它标志着复杂CSS ...

  7. Google Tango service outdated谷歌Tango的服务过时了

    If you device showed "tango service outdated." It means that your Tango Core need to be up ...

  8. jmeter 计数器 (可自动生成新数字、注册专用)

    1.打开jmeter,创建好线程组后,添加计数器 2.设置计数器 3.添加HTTP请求,验证所设置的计数器 4.填写对应参数 5.添加查看结果树,查看结果 6.修改一下线程属性 7.跑一下,看下结果就 ...

  9. leancloud 云引擎

    可以部署网站的云端,云代码的升级版.

  10. UI 设计概念介绍

    UI 设计概念介绍 http://www.slideshare.net/tedzhaoxa/ui-and-ue-design-basic