码迷,mamicode.com
首页 > 编程语言 > 详细

网卡速率变化导致paramiko模块timeout的失效,多线程超时控制解决办法。

时间:2018-01-13 12:47:03      阅读:301      评论:0      收藏:0      [点我收藏+]

标签:问题   图片   返回值   bug   help   term   user   一个   word   

起因:

      上周给几个集群的机器升级软件包,每个集群大概两千台服务器,但是在软件发包和批量执行命令的过程中有两个集群都遇到了问题,在批量执行命令的时候总是会在后面卡住久久不能退出,最后只好手动杀掉进程。

    如下图是sshpt批量执行命令时,到最后卡住久久不动,很久以后报出一个TypeError的异常,因为返回值不是命令输出的结果列表而是一个异常对象,这个异常并不是关键,是大妈对结果类型判断不全。真正原因应该是某台机器导致线程不能退出。

技术分享图片

sshpt支持timeout参数,-T 或者 --timeout

sshpt  —help 
-T <seconds>, --timeout=<seconds>
                Timeout (in seconds) before giving up on an SSH
                connection (default: 30)

看了一下sshpt关于timeout的代码,发现这个timeout仅仅在ssh.connect中用到,而exec_command调用中并没有传入timeout。

def paramikoConnect(host, username, password, timeout, port=22):     
    """Connects to 'host' and returns a Paramiko transport object to use in further communications"""
    # Uncomment this line to turn on Paramiko debugging (good for troubleshooting why some servers report connection failures)
    #paramiko.util.log_to_file('paramiko.log')
    ssh = paramiko.SSHClient()
    try:
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(host, port=port, username=username, password=password, timeout=timeout)  #ssh.connect中传入timeout
    except Exception, detail:
        # Connecting failed (for whatever reason)
        ssh = str(detail)
    return ssh

def sudoExecute(transport, command, password, run_as='root'):
    """Executes the given command via sudo as the specified user (run_as) using the given Paramiko transport object.
    Returns stdout, stderr (after command execution)"""
    stdin, stdout, stderr = transport.exec_command("sudo -S -u %s %s" % (run_as, command))   #exec_command中并没有timeout控制
    if stdout.channel.closed is False: # If stdout is still open then sudo is asking us for a password
        stdin.write('%s\n' % password)
        stdin.flush()
    return stdout, stderr


paramiko的代码中是支持对exec_command的timeout参数传入

class SSHClient (ClosingContextManager):
    def exec_command(
        self,
        command,
        bufsize=-1,
        timeout=None,    #支持timeout
        get_pty=False,
        environment=None,
    ):
   
        chan = self._transport.open_session(timeout=timeout)
        if get_pty:
            chan.get_pty()
        chan.settimeout(timeout)
        if environment:
        chan.update_environment(environment)
        chan.exec_command(command)
        stdin = chan.makefile('wb', bufsize)
        stdout = chan.makefile('r', bufsize)
        stderr = chan.makefile_stderr('r', bufsize)
        return stdin, stdout, stderr




网卡速率变化导致paramiko模块timeout的失效,多线程超时控制解决办法。

标签:问题   图片   返回值   bug   help   term   user   一个   word   

原文地址:http://blog.51cto.com/heqin/2060531

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!