为什么我可以比 Linux 使用捆绑命令更快地通过 ssh 返回结果?

为什么我可以比 Linux 使用捆绑命令更快地通过 ssh 返回结果?

我正在编写一个简短的 bash 脚本,其中涉及登录大约 100 个节点并使用我的用户名计算在 top 中运行的进程数,并且我试图将与 ssh 相关的进程全部合并到一个捆绑命令中:

ssh server-1 top -bn1 | grep 'program' | grep -c 'username'

当我执行此操作时,我注意到返回服务器的进程数大约需要 5 秒钟,这本身并不长。但是,当我想运行此命令大约 100 次时,最好加快速度。我可以编辑 .bash_profile 以注释掉以下几行:

if [ -f ~/.bashrc ]; then
    . ~/.bashrc
fi

从那里,我可以在大约 3 秒内手动完成输入 ssh、top/grep/grep 和 exit 命令的过程。考虑到 ssh 和 exit 过程合计仅需大约 1 秒(注释掉我的 .bash_profile),而 top/grep/grep 几乎是即时的,如果计算机执行命令,它应该比 3 秒快得多。但是,保持 .bash_profile 注释掉并不能提高捆绑 ssh 命令的速度,捆绑命令仍然需要大约 5 秒,而手动执行则需要 3 秒。有人能解释为什么捆绑命令比手动单独执行命令更慢,即使注释掉 .bash_profile 也是如此吗?

答案1

我可以做一个受过教育的猜测- 我假设当您手动运行会话时,您已经有另一个会话登录,并且 SSH 正在后台使用现有连接。当您编写此脚本时,SSH 需要协商一个全新的会话。

有很多方法可以加速 SSH 连接 - 请阅读https://www.tecmint.com/speed-up-ssh-connections-in-linux/- 尤其是第 3 部分,它允许你通过 ~/.ssh/config 文件中的以下内容重用 SSH 连接 -

Host *
ControlMaster auto
ControlPath  ~/.ssh/sockets/%r@%h-%p
ControlPersist 600

或者看看“autossh”,它对我来说效果很好。(从记忆中——那是 10 年前的事了——我在监控服务器启动时使用了 autossh -M)

话虽如此,请允许我建议,如果您退一步考虑,可能会有更好的方法来实现这一点 - 利用后台进程并并行执行多个 SSH 部分。专注于此将更快地返回结果(尽管如果与上述技术相结合会更好)。

您应该能够将您的 SSH 请求置于后台并将结果转储到一个或多个文件,然后等待它们全部完成、排序和呈现。

下面是一段简单的代码来展示这个概念(当然,这假设主机之间存在信任关系)

  #!/bin/bash

  TEMPFILE=/dev/shm/temp.$$

  for each in host1.name host2.name host3.name host4.name
  do
        ssh $each "ssh command(s) here" >> $TEMPFILE  &
  done
  wait
 
  cat $TEMPFILE
  rm $TEMPFILE

这里的神奇之处在于 -

  • SSH 行末尾的 & 将请求置于背景状态。
  • wait 命令等待所有后台进程退出。

相关内容