0

好的,所以这个问题的答案可能只是“停止使用并行 ssh 并使用 netmiko/paramiko 编写自己的代码。另外,已经升级到 python 3。”

但这是我的问题:我正在使用parallel-ssh尝试一次访问多达 80 个设备。这些设备是出了名的不可靠,并且它们偶尔会在提供一两行输出后冻结。然后,parallel-ssh 代码挂了几个小时,让脚本运行,直到我杀死它。一个周末后,我跳到运行脚本的虚拟机上,看到一份工作被卡住了 52 小时。

我的第一个代码的相关部分,即挂起的部分:

from pssh.pssh2_client import ParallelSSHClient
def remote_ssh(ip_list, ssh_user, ssh_pass, cmd):
  client = ParallelSSHClient(ip_list, user=ssh_user, password=ssh_pass, timeout=180, retry_delay=60, pool_size=100, allow_agent=False)
  result = client.run_command(cmd, stop_on_errors=False)
  return result

接下来我尝试的是channel_timout选项,因为如果获得命令输出需要超过 4 分钟,那么我知道设备冻结了,我需要继续并稍后在脚本中循环它:

from pssh.pssh_client import ParallelSSHClient
def remote_ssh(ip_list, ssh_user, ssh_pass, cmd):
  client = ParallelSSHClient(ip_list, user=ssh_user, password=ssh_pass, channel_timeout=180, retry_delay=60, pool_size=100, allow_agent=False)
  result = client.run_command(cmd, stop_on_errors=False)
  return result

这个版本从来没有真正连接到任何东西。有什么建议吗?除了 channel_timeout 之外,我找不到任何东西来尝试在一定时间后终止 ssh 会话。

4

1 回答 1

0

该代码在函数内创建一个客户端对象,然后将其输出run_command包括远程通道返回给 SSH 服务器。

由于该client函数永远不会返回该对象,因此它会超出范围并由 Python 收集垃圾,从而关闭连接。

尝试在关闭的连接上使用远程通道将永远不会奏效。如果您捕获卡住脚本的堆栈跟踪,则它很可能在使用远程通道或连接时挂起。

更改您的代码以使客户端保持活动状态。理想情况下,客户端也应该被重用。

from pssh.pssh2_client import ParallelSSHClient

def remote_ssh(ip_list, ssh_user, ssh_pass, cmd):
  client = ParallelSSHClient(ip_list, user=ssh_user, password=ssh_pass, timeout=180, retry_delay=60, pool_size=100, allow_agent=False)
  result = client.run_command(cmd, stop_on_errors=False)
  return client, result

在得出无法解决问题的结论之前,请确保您了解代码出错的地方,即捕获它挂起的位置的堆栈跟踪。同样的代码做同样的事情会以同样的方式破坏..

于 2017-11-23T11:29:23.220 回答