網卡速率變化導致paramiko模塊timeout的失效,多線程超時控制解決辦法。
阿新 • • 發佈:2018-01-13
context .com 判斷 cep util sha fff fail stdout 起因:
上周給幾個集群的機器升級軟件包,每個集群大概兩千臺服務器,但是在軟件發包和批量執行命令的過程中有兩個集群都遇到了問題,在批量執行命令的時候總是會在後面卡住久久不能退出,最後只好手動殺掉進程。
如下圖是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的失效,多線程超時控制解決辦法。