作业需求:

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

例子:

>>:run "df -h" --hosts 192.168.3.55 10.4.3.4

task id: 45334

>>: check_task 45334

>>:

注意,每执行一条命令,即立刻生成一个任务ID,不需等待结果返回,通过命令check_task TASK_ID来得到任务结果

思路解析:

分析需求其实可以发现,输入命令为消费者,执行命令是生产者,参照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. 消费者将结果存成字典,查询结果后删除。

关于疑问在测试的过程中发现

  while self.response is None:
self.connection.process_data_events()

在这段中如果没有消息返回就一直处于死循环也就是说,如果生产者挂掉一台,那我就会卡住,查看官方文档,对这个简单RPC实现也是延伸了下这个问题。

1. 如果没有服务器运行,客户应该如何应对?
2. 客户端是否应该对RPC有某种超时?
3. 如果服务器发生故障并引发异常,是否应将其转发给客户端?
4. 在处理之前防止无效的传入消息(例如检查边界)。

思维导图:

核心代码:

消费者:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Time:2017/12/6 15:52
__Author__ = 'Sean Yao'
import pika
import uuid class CommandToRabbitmq(object):
def __init__(self):
self.connection = pika.BlockingConnection(pika.ConnectionParameters(
host='localhost')) self.channel = self.connection.channel() result = self.channel.queue_declare(exclusive=True)
self.callback_queue = result.method.queue self.channel.basic_consume(self.on_response, no_ack=True,
queue=self.callback_queue) def on_response(self, ch, method, props, body):
if self.corr_id == props.correlation_id:
self.response = body def call(self, command, host):
self.response = None
self.corr_id = str(uuid.uuid4())
ack = self.channel.basic_publish(exchange='',
routing_key=host,
properties=pika.BasicProperties(
reply_to=self.callback_queue,
correlation_id=self.corr_id),
body=str(command))
while self.response is None:
# 等待消息
self.connection.process_data_events() task_id = self.corr_id
res = self.response.decode()
tmp_dict[task_id] = res
print('task_id: %s host: %s cmd: %s ' % (self.corr_id, host, command))
return self.corr_id, self.response.decode() def help():
print('Usage: run "df -h" --hosts 127.0.0.1 192.168.84.66 ')
print(' check_task 54385061-aa3a-400f-8a21-2be368e66493 ')
print(' check_task_all') def start(command_input):
command_list = command_input.split()
if command_list[0] == 'check_task':
try:
print(tmp_dict[command_list[1]])
del tmp_dict[command_list[1]]
except IndexError:
help()
elif command_list[0] == 'run':
# 获取命令主机,并循环执行
try:
ip_hosts_obj = command_input.split('run')
hosts_obj = (ip_hosts_obj[1].split('--hosts'))
hosts = hosts_obj[1].strip().split()
command = command_input.split("\"")[1]
for host in hosts:
try:
command_rpc.call(command, host)
except TypeError and AssertionError:
break
except IndexError:
print('-bash: %s command not found' % command_input)
help()
elif command_list[0] == 'check_task_all':
for index, key in enumerate(tmp_dict.keys()):
print(index, 'task_id: %s' % key)
elif command_list[0] == 'help':
help()
else:
print('-bash: %s command not found' % command_input)
help() command_rpc = CommandToRabbitmq()
exit_flag = True
tmp_dict = {}
help()
while exit_flag:
command_input = input('请输入命令>>>:').strip()
if len(command_input) == 0:
continue
else:
start(command_input)

生产者:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Time:2017/12/6 15:52
__Author__ = 'Sean Yao'
import pika
import time
import subprocess
import platform connection = pika.BlockingConnection(pika.ConnectionParameters(
host='localhost')) # rabbitmq 设有权限的连接
# connection = pika.BlockingConnection(pika.ConnectionParameters(
# host='192.168.1.105',credentials=pika.PlainCredentials('admin', 'admin'))) channel = connection.channel()
channel.queue_declare(queue='127.0.0.1')
os_res = platform.system() # def command(cmd, task_id):
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_request(ch, method, props, body):
cmd = body.decode()
respone = command(cmd)
ch.basic_publish(exchange='',
routing_key=props.reply_to,
properties=pika.BasicProperties(correlation_id=props.correlation_id),
body=respone)
ch.basic_ack(delivery_tag=method.delivery_tag) channel.basic_qos(prefetch_count=1)
channel.basic_consume(on_request, queue='127.0.0.1')
print(" [x] Awaiting RPC requests")
channel.start_consuming()

程序测试样图:

python作业(第十一周)基于RabbitMQ rpc实现的主机管理的更多相关文章

  1. 基于RabbitMQ rpc实现的主机管理

    要求: 文件分布: 流程图: import pika import os import socket class Server(object): def __init__(self, queuenam ...

  2. python第十一周:RabbitMQ、Redis

    Rabbit Mq消息队列 RabbitMQ能为你做些什么? 消息系统允许软件.应用相互连接和扩展.这些应用可以相互链接起来组成一个更大的应用,或者将用户设备和数据进行连接.消息系统通过将消息的发送和 ...

  3. Python并行编程(十一):基于进程的并行

    1.基本概念 多进程主要用multiprocessing和mpi4py这两个模块. multiprocessing是Python标准库中的模块,实现了共享内存机制,可以让运行在不同处理器核心的进程能读 ...

  4. linux作业--第十一周

    1. 导入hellodb.sql生成数据库 (1) 在students表中,查询年龄大于25岁,且为男性的同学的名字和年龄 (2) 以ClassID为分组依据,显示每组的平均年龄 (3) 显示第2题中 ...

  5. python第六十三天-- 第十一周作业

    题目:基于RabbitMQ rpc实现的主机管理 需求: 可以对指定机器异步的执行多个命令例子:>>:run "df -h" --hosts 192.168.3.55 ...

  6. 2017-2018-2 20179205《网络攻防技术与实践》第十一周作业 SQL注入攻击与实践

    <网络攻防技术与实践>第十一周作业 SQL注入攻击与实践 1.研究缓冲区溢出的原理,至少针对两种数据库进行差异化研究 缓冲区溢出原理   在计算机内部,输入数据通常被存放在一个临时空间内, ...

  7. 2017-2018-2 1723《程序设计与数据结构》第十一周作业 & 实验三 & (总体)第三周结对编程 总结

    作业地址 第十一次作业:https://edu.cnblogs.com/campus/besti/CS-IMIS-1723/homework/1933 (作业界面已评分,可随时查看,如果对自己的评分有 ...

  8. python作业ATM(第五周)

    作业需求: 额度 15000或自定义. 实现购物商城,买东西加入 购物车,调用信用卡接口结账. 可以提现,手续费5%. 支持多账户登录. 支持账户间转账. 记录每月日常消费流水. 提供还款接口. AT ...

  9. 基于RabbitMQ的跨平台RPC框架

    RabbitMQRpc protocobuf RabbitMQ 实现RPC https://www.cnblogs.com/LiangSW/p/6216537.html 基于RabbitMQ的RPC ...

随机推荐

  1. 小甲鱼-005python数据类型

    整型:python3整形理论上没有长度限制,很容易进行大数的运算. 浮点型:没有小数点就是整形,有小数点就是浮点型 e记法:科学技术法1.5e3,即1500,1.3e-4即0.0001.3,e记法是浮 ...

  2. 设置redis 密码

    redis配置密码 1.通过配置文件进行配置 yum方式安装的redis配置文件通常在/etc/redis.conf中,打开配置文件找到 [plain] view plain copy require ...

  3. Linux常用的一些基础命令

    删除 rm -rvf * -f:强制删除文件或文件夹 -r:递归的删除文件或文件夹 -i:删除文件或文件夹前需要确认 -v:详细显示进行步骤 查看 ls ll        ls -l cat mor ...

  4. UMG设置组件自适应居中或靠边

    转自:http://aigo.iteye.com/blog/2297430 比如你的UI中有些组件需要居中显示,有些需要始终在右上角并且与上边框和右边框保持固定的距离等等,对于这种需要动态适应屏幕分辨 ...

  5. LightGBM优势总结

    效率和内存上的提升 1) 在训练决策树计算切分点的增益时,xgboost采用预排序,即需要对每个样本的切分位置都要计算一遍,所以时间复杂度是O(#data). 而LightGBM则是将样本离散化为直方 ...

  6. RmNet,CDC-ECM ,NDIS,RNDIS区别

    RmNet和CDC-ECM区别:更像是两种拨号方式的区别,RmNet获取公网IP,ECD-ECM获取局域网IP. 在高通平台上,rmnet driver 和标准的CDC-ECM是有区别的,rmnet ...

  7. 运用map并于执行期指定排序准则

    该例展示以下技巧: 如何使用map 如何撰写和使用仿函数 如何在执行期定义排序规则 如何在"不在乎大小写"的情况下比较字符串 #include<iostream> #i ...

  8. Django中间件执行流程

    中间件函数是 django 框架为我们预留的函数接口, 让我们可以干预请求和应答的过程 1. 获取浏览器端的IP地址: 使用 request.META[‘REMOTE_ADDR’] 2. 使用中间件 ...

  9. 洛谷:P1087 FBI树 P1030 求先序排列 P1305 新二叉树

    至于为啥把这三个题放到一起,大概是因为洛谷的试炼场吧,三道树的水题,首先要理解 先序中序后序遍历方法. fbi树由于数量小,在递归每个区间时,暴力跑一遍区间里的数,看看是否有0和1.至于递归的方法,二 ...

  10. jenkins API

    1.curl http://199.168.299.99:8080/job/send_message/lastBuild/api/json --user administrator:1234  获取j ...