Python 如何提高paramiko的性能
我的Paramiko有一个性能问题,我做了很多测试,我不知道如何修复它。我有一个脚本,在一个外部SSH服务器上运行许多命令,它运行得很好,但由于时间的原因,它非常长。因此,脚本在每个命令发送后的1秒内不执行任何操作 目前,它发送17条命令,因此用户正在等待23条命令。根据命令,脚本不需要等待1s,所以我想知道脚本何时结束从服务器接收数据,然后直接发送新命令 我试图签入Channel.recv或BufferPipe,但没有成功 您将在下面找到我如何发送命令:Python 如何提高paramiko的性能,python,ssh,paramiko,Python,Ssh,Paramiko,我的Paramiko有一个性能问题,我做了很多测试,我不知道如何修复它。我有一个脚本,在一个外部SSH服务器上运行许多命令,它运行得很好,但由于时间的原因,它非常长。因此,脚本在每个命令发送后的1秒内不执行任何操作 目前,它发送17条命令,因此用户正在等待23条命令。根据命令,脚本不需要等待1s,所以我想知道脚本何时结束从服务器接收数据,然后直接发送新命令 我试图签入Channel.recv或BufferPipe,但没有成功 您将在下面找到我如何发送命令: for comman
for command in commands:
try:
chan.send(command)
while chan.recv_ready() is False:
time.sleep(1)
output += chan.recv(2048)
您可以检查命令的退出状态-无需使用time.sleep。 一种可能的解决办法: 首先,定义一个连接到ssh服务器的函数:
def createSSHClient(server, port, user, password):
client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(server, port, user, password)
return client
创建该客户端:
some_command = 'YOUR_COMMAND'
sshClient = createSSHClient(host, port, username, password)
执行命令并检查其退出状态
stdin, stdout, stderr = sshClient.exec_command(some_command)
if (stdout.channel.recv_exit_status() != 0):
print "command failed"
else:
print "command succeeded"
我修复了该代码的问题:
for command in list_commands:
try:
chan.send(command)
while chan.recv_ready() is False:
time.sleep(0)
while chan.recv_ready():
output += chan.recv(2048)
time.sleep(0.2)
我赢得了16条命令的13秒,看起来很有价值。性能问题可能与paramiko本身有关。当我编写一个程序来检查十台服务器的状态,检查大约十二个参数时,我发现即使并行十个检查,也需要大约9-10秒的时间。当我通过subprocess.check_输出将paramiko替换为ssh时,性能提高到2秒左右 以下是关键部分,包括并行化:
def ServerSummary(sinp):
server,ip=sinp.split('|')
def Remote(cmd, IP, user='root'):
cmd='''ssh %s@%s %s'''%(user, IP, cmd)
lines = subprocess.check_output(cmd.split())
return lines
tcp=Remote('ss -s|grep TCP:',ip).split()
tcp=str(tcp[1])
。
.
. # 其他状态信息被收集并作为制表符分隔的字符串返回
return '''%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s'''% (server,
html,mysql,memcache,PD,DBStatus,tcp,load1,load2,load3,size,used)
。
.
. # 这是获取服务器及其IP列表的主要部分,并启动例程以并行方式收集每台服务器的信息。收集完所有信息后,将按服务器名称排序并打印出来
Sout=[]; S=[]
for Owner in ['MyServers','YourServers']:
Servers=GetActiveServers(sids=[Owner])
for server,ip in Servers:
if server in ['INFRARED',]: continue
s='%s|%s'%(server,ip)
S.append(s)
from multiprocessing import Pool
p = Pool(len(S))
Sout.append(p.map(ServerSummary, S))
Sout=sorted(Sout[0])
for i in Sout: print i
这是输出的一个示例:
time python CheckAllServersTSV.py
Server HTML MySQL Memc ProcD QPS TCP Load1 Load2 Load3 Disk Used
ServerD ok ok NO ok 6.303 14 0.09 0.06 0.03 20G 38%
ServerE ok ok NO ok 7.131 27 0.16 0.28 0.48 20G 30%
ServerI ok ok ok NO 13.52 161 0.05 0.01 0.00 35G 23%
ServerJ ok ok NO ok 4.629 62 0.00 0.02 0.01 56G 27%
ServerK ok ok NO ok 3.169 13 0.05 0.01 0.00 35G 17%
ServerL ok ok ok ok 2.621 17 0.05 0.05 0.04 35G 35%
ServerM ok ok NO ok 0.043 13 0.07 0.10 0.06 35G 13%
ServerQ ok ok NO NO 1.074 15 0.05 0.01 0.00 35G 14%
ServerP ok ok ok NO 2.230 33 0.08 0.03 0.02 35G 25%
ServerR ok ok NO ok 0.856 11 0.05 0.01 0.00 35G 11%
real 0m2.079s
user 0m0.628s
sys 0m0.780s
你的代码无法工作,你只能使用exec命令一次,否则你必须打开一个新的通道,无论如何,我将尝试使用多个通道。事实上,我使用了多个通道(我有相同的情况,我必须执行几个命令)。我记得在退出代码出现问题时,我添加了sshClient.exec_命令(some_命令,get_pty=True),但不确定这是否是解决方案。这是我能帮你的最好的了。