一、作业需求

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()

服务端

RabbitMQ-RPC版主机管理程序的更多相关文章

  1. 老男孩Day12作业:RabbitMQ-RPC版主机管理程序

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

  2. 【python】-- RabbitMQ RPC模型

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

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

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

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

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

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

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

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

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

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

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

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

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

  9. python作业(第十一周)基于RabbitMQ rpc实现的主机管理

    作业需求: 可以对指定机器异步的执行多个命令 例子: >>:run "df -h" --hosts 192.168.3.55 10.4.3.4 task id: 453 ...

随机推荐

  1. HDU5740 Glorious Brilliance【最短路 KM匹配】

    HDU5740 Glorious Brilliance 题意: 给出一张不一定合法的染色图,每次可以交换相邻两点的颜色,问最少多少次能使染色图合法 合法的染色图相邻点的颜色不能相同 题解: 首先要确定 ...

  2. 【bzoj 2163】复杂的大门(算法效率--拆点+贪心)

    题目:你去找某bm玩,到了门口才发现要打开他家的大门不是一件容易的事-- 他家的大门外有n个站台,用1到n的正整数编号.你需要对每个站台访问一定次数以后大门才能开启.站台之间有m个单向的传送门,通过传 ...

  3. Atcoder(134)E - Sequence Decomposing

    E - Sequence Decomposing Time Limit: 2 sec / Memory Limit: 1024 MB Score : 500500 points Problem Sta ...

  4. - Visible Trees HDU - 2841 容斥原理

    题意: 给你一个n*m的矩形,在1到m行,和1到n列上都有一棵树,问你站在(0,0)位置能看到多少棵树 题解: 用(x,y)表示某棵树的位置,那么只要x与y互质,那么这棵树就能被看到.不互质的话说明前 ...

  5. JavaScript——原型

    原型中的原先设定的值不能改变!!!

  6. 无所不能的Embedding6 - 跨入Transformer时代~模型详解&代码实现

    上一章我们聊了聊quick-thought通过干掉decoder加快训练, CNN-LSTM用CNN作为Encoder并行计算来提速等方法,这一章看看抛开CNN和RNN,transformer是如何只 ...

  7. Leetcode(884)-索引处的解码字符串

    给定一个编码字符串 S.为了找出解码字符串并将其写入磁带,从编码字符串中每次读取一个字符,并采取以下步骤: 如果所读的字符是字母,则将该字母写在磁带上. 如果所读的字符是数字(例如 d),则整个当前磁 ...

  8. Install wx

    Ubuntu 16.04: 由于是PY交易, 实际上是安装wxPython: pip install -U \ -f https://extras.wxpython.org/wxPython4/ext ...

  9. Ubuntu16安装Caffe+Python3缺少libboost

    如果在/usr/lib/x86_64-linux-gnu中找到libboost_python-py3.5.so, 则 sudo ln -s libboost_python-py3.5.so libbo ...

  10. 如何在手机上实现 H5 页面全屏显示

    如何在手机上实现 H5 页面全屏显示 fullscreen 隐藏头部地址栏 隐藏底部导航栏 refs xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许注册用户才 ...