You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bash脚本多SSH会话并行执行问题及优化方案咨询

更优的Bash SSH会话并行化方案及问题解决

问题分析

你当前的脚本直接在循环中将每个SSH任务后台执行,同时发起30+个SSH连接时,可能触发本地/远程系统的连接限制、并发会话上限,或是因未等待任务完成导致部分进程异常终止,最终出现用户创建随机遗漏的情况。虽然调整了net.core.somaxconn和maxlogins,但这些参数未必覆盖所有限制(比如远程服务器sshd的并发配置、本地进程数限制等)。

优化方案

1. 控制并发数,避免瞬间资源过载

全量后台启动会瞬间压满系统资源,建议用分批并行或并发数控制的方式,降低连接失败概率:

用xargs控制并发

将服务器列表转换为每行一个,通过xargs -P指定最大并发数(示例设为10,可根据系统承受能力调整):

SSH="/bin/ssh -o ConnectTimeout=60 -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -p 61313"

# 将空格分隔的SERVERS转为每行一个,再启动并发任务
echo "$SERVERS" | tr ' ' '\n' | xargs -I {} -P 10 bash -c '
  echo "adding user user1 in $1"
  '"$SSH"' $1 "sudo echo \"user1:pass1:1313:1015::/home/user1:/bin/rbash\" | sudo newusers"
' _ {}

用GNU Parallel(更灵活)

如果系统已安装parallel,可以更简洁地控制并发,还支持失败重试:

SSH="/bin/ssh -o ConnectTimeout=60 -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -p 61313"

# 定义单服务器处理函数
add_user() {
  server=$1
  echo "adding user user1 in $server"
  $SSH "$server" "sudo echo \"user1:pass1:1313:1015::/home/user1:/bin/rbash\" | sudo newusers"
}

# 导出函数和变量给parallel使用
export -f add_user
export SSH

# 启动15个并发任务,可加--retries 2实现失败重试
echo "$SERVERS" | tr ' ' '\n' | parallel -j 15 add_user

2. 确保任务执行完成并捕获错误

原脚本注释掉了wait,可能导致脚本在后台SSH任务完成前就退出,部分进程被强制终止。即使控制并发,也要确保所有任务执行完毕:

SSH="/bin/ssh -o ConnectTimeout=60 -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -p 61313"

# 存储所有后台进程PID
pids=()

for i in $SERVERS
do
  echo "adding user user1 in $i"
  $SSH $i "sudo echo \"user1:pass1:1313:1015::/home/user1:/bin/rbash\" | sudo newusers" &
  pids+=($!)
done

# 等待所有进程完成并检查退出状态
for pid in "${pids[@]}"
do
  wait $pid
  if [ $? -ne 0 ]; then
    echo "任务PID $pid 执行失败"
  fi
done

3. 优化SSH连接参数,减少资源消耗

  • 移除-tt参数:批量执行命令无需强制分配伪终端,该参数会增加额外资源开销,甚至导致连接异常。
  • 启用SSH连接复用:通过ControlMaster复用已建立的连接,大幅减少重复创建会话的资源消耗:
# 先创建控制目录
mkdir -p ~/.ssh/controlmasters

SSH="/bin/ssh -o ConnectTimeout=60 -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -p 61313 \
  -o ControlMaster=auto -o ControlPath=~/.ssh/controlmasters/%h:%p:%r -o ControlPersist=60s"

4. 检查远程服务器限制

除本地参数外,需排查远程服务器的以下配置:

  • sshd_config中的MaxStartups(控制并发SSH连接数,默认值为10:30:100,可适当调大)
  • sshd_config中的MaxSessions(单个SSH连接的最大会话数)
  • 远程系统的ulimit限制,比如用户最大进程数

25个用户批量处理建议

如果要为25个用户分别在30+台服务器创建,可将用户信息整理为列表,结合连接复用和并发控制批量执行:

# 用户信息列表,每行一条
users=(
"user1:pass1:1313:1015::/home/user1:/bin/rbash"
"user2:pass2:1314:1015::/home/user2:/bin/rbash"
# ... 剩余23个用户信息
)

SSH="/bin/ssh -o ConnectTimeout=60 -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -p 61313 \
  -o ControlMaster=auto -o ControlPath=~/.ssh/controlmasters/%h:%p:%r -o ControlPersist=60s"

# 定义单服务器处理所有用户的函数
process_server() {
  server=$1
  echo "处理服务器 $server 的所有用户"
  for user_info in "${users[@]}"
  do
    user=$(echo "$user_info" | cut -d: -f1)
    echo "在 $server 创建用户 $user"
    echo "$user_info" | $SSH "$server" "sudo newusers"
  done
}

export -f process_server
export SSH users

# 启动10个并发任务处理服务器
echo "$SERVERS" | tr ' ' '\n' | parallel -j 10 process_server

内容的提问来源于stack exchange,提问作者Giancarlo D

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 14:52:51