gpt4 book ai didi

bash - 使用 bash 和 ssh 的远程任务队列用于可变数量的在线工作人员

转载 作者:行者123 更新时间:2023-11-29 09:00:57 25 4
gpt4 key购买 nike

我想使用批处理将工作从主服务器分发到多个工作服务器。

理想情况下,我会有一个包含要执行的任务列表的 tasks.txt 文件

cmd args 1
cmd args 2
cmd args 3
cmd args 4
cmd args 5
cmd args 6
cmd args 7
...
cmd args n

每个工作服务器将使用 ssh 连接,读取文件并将每一行标记为正在进行或已完成

#cmd args 1  #worker1 - done
#cmd args 2 #worker2 - in progress
#cmd args 3 #worker3 - in progress
#cmd args 4 #worker1 - in progress
cmd args 5
cmd args 6
cmd args 7
...
cmd args n

我知道如何建立 ssh 连接、读取文件和远程执行,但不知道如何使读写成为原子操作,以免出现 2 台服务器启动相同任务的情况,并且如何更新线路。

我希望每个工作人员转到任务列表并锁定列表中的下一个可用任务,而不是服务器主动命令工作人员,因为我将拥有灵活数量的工作人员克隆,我将启动或关闭这些工作人员根据我需要完成任务的速度。

更新:

我对工作脚本的想法是:

#!/bin/bash

taskCmd=""
taskLine=0
masterSSH="ssh usr@masterhost"
tasksFile="/path/to/tasks.txt"

function getTask(){
while [[ $taskCmd == "" ]]
do
sleep 1;
taskCmd_and_taskLine=$($masterSSH "#read_and_lock_next_available_line $tasksFile;")
taskCmd=${taskCmd_and_taskLine[0]}
taskLine=${taskCmd_and_taskLine[1]}
done
}

function updateTask(){
message=$1
$masterSSH "#update_currentTask $tasksFile $taskLine $message;"
}


function doTask(){
return $taskCmd;
}


while [[ 1 -eq 1 ]]
do
getTask
updateTask "in progress"
doTask
taskErrCode=$?
if [[ $taskErrCode -eq 0 ]]
then
updateTask "done, finished successfully"
else
updateTask "done, error $taskErrCode"
fi
taskCmd="";
taskLine=0;

done

最佳答案

您可以使用flock 来并发访问文件:

exec 200>>/some/any/file ## create a file descriptor
flock -w 30 200 ## concurrently access /some/any/file, timeout of 30 sec.

您可以将文件描述符指向您的任务列表或任何其他文件,但当然要使用相同的文件才能 工作。一旦创建它的进程完成或失败,锁就会被删除。您也可以在不再需要时自行移除锁:

flock -u 200

用法示例:

ssh user@x.x.x.x '
set -e
exec 200>>f
echo locking...
flock -w 10 200
echo working...
sleep 5
'
如果任何步骤失败,

set -e 将使脚本失败。玩转 sleep 时间并并行执行此脚本。一次只会执行一个sleep

关于bash - 使用 bash 和 ssh 的远程任务队列用于可变数量的在线工作人员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35081087/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com