Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何提高paramiko的性能_Python_Ssh_Paramiko - Fatal编程技术网

Python 如何提高paramiko的性能

Python 如何提高paramiko的性能,python,ssh,paramiko,Python,Ssh,Paramiko,我的Paramiko有一个性能问题,我做了很多测试,我不知道如何修复它。我有一个脚本,在一个外部SSH服务器上运行许多命令,它运行得很好,但由于时间的原因,它非常长。因此,脚本在每个命令发送后的1秒内不执行任何操作 目前,它发送17条命令,因此用户正在等待23条命令。根据命令,脚本不需要等待1s,所以我想知道脚本何时结束从服务器接收数据,然后直接发送新命令 我试图签入Channel.recv或BufferPipe,但没有成功 您将在下面找到我如何发送命令: for comman

我的Paramiko有一个性能问题,我做了很多测试,我不知道如何修复它。我有一个脚本,在一个外部SSH服务器上运行许多命令,它运行得很好,但由于时间的原因,它非常长。因此,脚本在每个命令发送后的1秒内不执行任何操作

目前,它发送17条命令,因此用户正在等待23条命令。根据命令,脚本不需要等待1s,所以我想知道脚本何时结束从服务器接收数据,然后直接发送新命令

我试图签入Channel.recv或BufferPipe,但没有成功

您将在下面找到我如何发送命令:

         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),但不确定这是否是解决方案。这是我能帮你的最好的了。