python--基於RabbitMQ rpc實現的主機管理

來源:互聯網
上載者:User

標籤:需要   標識   guest   字串   etc   result   gnu   +=   .exe   

要求:

可以非同步執行多個命令
對多台機器
>>:run "df -h" --hosts 192.168.3.55 10.4.3.4
task id: 45334
>>: check_task 45334
>>:

思考:
1、分解其中需要實現的功能
(1)命令是發到遠程主機上執行的,命令放在隊列裡,再發到主機處理,主機執行完結果放在隊列裡,提交命令的人自取。
就需要2個進程,一個client,提交命令,取結果,一個server,處理命令,放結果
(2)發送命令的時候,exchange決定往哪個隊列放訊息,每個server取自己的命令,用ip作為篩選的binding_key
(3)取結果的時候,就用預設的exchange,直接往reply_to的隊列裡放

server端
 1 #rabbitMQserver=‘10.21.147.189‘ 2 rabbitMQserver=‘localhost‘ 3  4 import pika 5 import os 6 import socket 7  8 class server(object): 9     def __init__(self):10         self.connection=pika.BlockingConnection(pika.ConnectionParameters(rabbitMQserver))11         self.channel=self.connection.channel()12         self.channel.exchange_declare(exchange=‘cmd‘,exchange_type=‘topic‘)13         self.queue_default = self.channel.queue_declare(exclusive=True)14         self.quname = self.queue_default.method.queue15         # 擷取本機ip作為binding_key,binding_key的格式是以點分隔的一系列字串,client發過來的訊息,routing_key滿足server的binding_key匹配原則,就會加入server連的那個queue16         self.hostip=socket.gethostbyname(socket.gethostname())17         self.binding_key=‘#.‘+self.hostip+‘.#‘18         print("binding_key: %s" % self.binding_key)19         self.channel.queue_bind(queue=self.quname, exchange=‘cmd‘, routing_key=self.binding_key)20         self.channel.basic_qos(prefetch_count=1)21 22         self.channel.basic_consume(self.execcmd,queue=self.quname,no_ack=False)23         self.channel.start_consuming()24         return25 26     def execcmd(self,ch,method,props,body):27         cmd=bytes.decode(body)28         print("[*] Received %s" % cmd)29         result = os.popen(cmd).read()30         print(result)31         ch.basic_publish(32             exchange=‘‘,33             routing_key=props.reply_to,34             properties=pika.BasicProperties(35                 correlation_id=props.correlation_id36             ),37             body=result38         )39         ch.basic_ack(delivery_tag=method.delivery_tag)40         return41 42 se=server()

 



client端
 1 import pika 2 import uuid 3  4 #rabbitMQserver=‘10.21.147.189‘ 5 rabbitMQserver=‘localhost‘ 6  7 class client(object): 8     def __init__(self): 9         self.cmdid={}10         self.connection = pika.BlockingConnection(pika.ConnectionParameters(rabbitMQserver))11         self.channel = self.connection.channel()12         self.channel.exchange_declare(exchange=‘cmd‘, exchange_type=‘topic‘)13 14         #回寫result的隊列用預設產生的,需要取得名字,exclusive定為True表示只能有本client消費這個queue15         self.result=self.channel.queue_declare(exclusive=True)16         self.resultqueue=self.result.method.queue17         return18 19     def showcmdid(self):20         print("-----命令標識如下:--------")21         for id,hosts in self.cmdid.items():22             print("cmdid:%s run on hosts: %s"%(id,hosts))23         return24 25     def callcmd(self,cmdinput):26         #如果是call命令,格式是 call+"命令"+ --host + 一串ip地址27         #首先判斷格式對不對,至少4個參數28         msglist=cmdinput.split()29         argnum=len(msglist)30         if argnum<4:31             print("Wrong cmd. Input again.")32             return33         #其次,命令是第二個參數,命令用雙引號標記,所以要strip34         msg = msglist[1].strip("\"")35         #然後,第三個是--host,第四個開始是ip,ip當作routing_key36         routing_key=msglist[3]37         i=438         while i < argnum:39             routing_key=routing_key+‘.‘+msglist[i]40             i+=141         print("routing_key: %s"%routing_key)42         #再然後,產生一個隨機數,把他作為訊息的屬性參數43         self.corr_id=str(uuid.uuid4())44         self.cmdid[self.corr_id]=msglist[3:]45         print("命令標識:%s"%self.corr_id)46         #然後,把訊息發到exchange,routing_key,corr_id當作參數發布47         self.channel.basic_publish(48             exchange=‘cmd‘,49             routing_key=routing_key,50             body=msg,51             properties=pika.BasicProperties(52                 reply_to=self.resultqueue,53                 correlation_id=self.corr_id54             )55         )56         print("[*] Send message %s" % msg)57         return58 59     def on_response(self,ch,method,props,body):60         if self.targetcmdid==props.correlation_id:61             self.response=bytes.decode(body)62             print(self.response)63         ch.basic_ack(delivery_tag=method.delivery_tag)64         return65 66     def getres(self,cmdinput):67         msglist = cmdinput.split()68         self.targetcmdid=msglist[1]69         self.response=None70         self.channel.basic_consume(self.on_response,queue=self.resultqueue)71         while self.response is None:72             self.connection.process_data_events()73         return74 75 cl=client()76 while True:77     msginput=input(">>: ").strip()78     if msginput.startswith(‘call‘):79         cl.callcmd(msginput)80     elif msginput.startswith(‘get‘):81         cl.getres(msginput)82     elif msginput.startswith(‘show‘):83         cl.showcmdid()84     elif msginput.startswith(‘exit‘):85         cl.connection.close()86         exit(0)87     else:88         print("Wrong cmd. Input again.")89         continue

目前沒有驗證遠程登陸rabbitMQ server的情況,應該是需要配置使用者名稱密碼,不能用預設的guest/guest。不過以上功能是實現了。

python--基於RabbitMQ rpc實現的主機管理

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.