如何在单个时间点在不同的远程计算机上运行单个命令

如何在单个时间点在不同的远程计算机上运行单个命令

我有以下 shell 脚本,它循环运行以触发 3 台不同机器上的性能测试。我希望在 3 台机器上验证后,它会同时触发测试。就像我同时向3台机器发送curl命令一样。

#!/bin/sh

IP_Addresses=(192.168.2.33,192.168.2.34,192.168.2.35)

triggerPerformanceTest(){ 
    for iplist in $(echo $IP_Addresses | sed "s/,/ /g")
    do
        echo "Validating the health end point in the remote server"    
        HTTP_RESPONSE=$(curl -m 1800 --silent --write-out "HTTPSTATUS:%{http_code}" -X GET http://${iplist}:9096/health)
        HTTP_STATUS=$(echo $HTTP_RESPONSE | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
        HTTP_BODY=$(echo $HTTP_RESPONSE | sed -e 's/HTTPSTATUS\:.*//g')
            if [ $HTTP_STATUS -eq 200  ] && [ $HTTP_BODY = "OK" ]; then
                echo "Success!! it seems the health service is ruuning in the target machine"
                echo "Starting the Jmeter Test"
            else
                echo "The health end point of the nodejs service return exit code 1, let the service start on the remote host"
                sleep 20
                HTTP_RESPONSE_NEW=$(curl -m 1800 --silent --write-out "HTTPSTATUS:%{http_code}" -X GET http://${iplist}:9096/health)
                HTTP_STATUS_NEW=$(echo $HTTP_RESPONSE_NEW | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
                HTTP_BODY_NEW=$(echo $HTTP_RESPONSE_NEW | sed -e 's/HTTPSTATUS\:.*//g')
                count=2
                echo "Re-validating the health end point in the remote server"
                    while [ $HTTP_STATUS_NEW -ne 200 ] && [ $HTTP_BODY_NEW != "OK" ]
                    do
                        echo "Waiting for the Node-js service to start on the remote server"
                        sleep 5
                        HTTP_RESPONSE_FINAL=$(curl -m 1800 --silent --write-out "HTTPSTATUS:%{http_code}" -X GET http://${iplist}:9096/health)
                        HTTP_STATUS_FINAL=$(echo $HTTP_RESPONSE_NEW | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
                        HTTP_BODY_FINAL=$(echo $HTTP_RESPONSE_NEW | sed -e 's/HTTPSTATUS\:.*//g')

                        count=`expr $count + 1`
                            if [ $count -eq 0 ]
                            then   
                                break
                            else
                                continue
                            fi
                    done
                        echo "Starting the Jmeter Test"
            fi
    done
}

triggerPerformanceTest $IP_Addresses

所以我的计划是将这三个curl命令放入一个数组元素并调用它们,但现在它们将是一个接一个。有没有办法可以在 3 台机器上并行触发它们?就像一次性调用下面的命令一样

curl http://192.168.2.33:9096/triggerPerformanceTest
curl http://192.168.2.34:9096/triggerPerformanceTest
curl http://192.168.2.35:9096/triggerPerformanceTest

或者有什么更好的方法来解决这个问题?我能想到的是在目标机器上实现逻辑,该逻辑将触发延迟测试,这意味着第一台机器将延迟测试几毫秒,第二台机器将延迟比第一台和第三台延迟更短的毫秒(0)。

答案1

尝试这个,

#!/bin/bash

IP_Addresses=(192.168.2.33 192.168.2.34 192.168.2.35)

triggerPerformanceTest(){ 
        iplist=$1
        LOG=/tmp/$iplist.log
        echo "Validating the health end point in the remote server"  >> $LOG
        HTTP_RESPONSE=$(curl -m 1800 --silent --write-out "HTTPSTATUS:%{http_code}" -X GET http://${iplist}:9096/health)
        HTTP_STATUS=$(echo $HTTP_RESPONSE | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
        HTTP_BODY=$(echo $HTTP_RESPONSE | sed -e 's/HTTPSTATUS\:.*//g')
            if [ $HTTP_STATUS -eq 200  ] && [ $HTTP_BODY = "OK" ]; then
                echo "Success!! it seems the health service is ruuning in the target machine" >> $LOG
                echo "Starting the Jmeter Test" >> $LOG
            else
                echo "The health end point of the nodejs service return exit code 1, let the service start on the remote host" >> $LOG
                sleep 20
                HTTP_RESPONSE_NEW=$(curl -m 1800 --silent --write-out "HTTPSTATUS:%{http_code}" -X GET http://${iplist}:9096/health)
                HTTP_STATUS_NEW=$(echo $HTTP_RESPONSE_NEW | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
                HTTP_BODY_NEW=$(echo $HTTP_RESPONSE_NEW | sed -e 's/HTTPSTATUS\:.*//g')
                count=2
                echo "Re-validating the health end point in the remote server" >> $LOG
                    while [ $HTTP_STATUS_NEW -ne 200 ] && [ $HTTP_BODY_NEW != "OK" ]
                    do
                        echo "Waiting for the Node-js service to start on the remote server" >> $LOG
                        sleep 5
                        HTTP_RESPONSE_FINAL=$(curl -m 1800 --silent --write-out "HTTPSTATUS:%{http_code}" -X GET http://${iplist}:9096/health)
                        HTTP_STATUS_FINAL=$(echo $HTTP_RESPONSE_NEW | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
                        HTTP_BODY_FINAL=$(echo $HTTP_RESPONSE_NEW | sed -e 's/HTTPSTATUS\:.*//g')
                        $HTTP_STATUS_NEW=$((HTTP_STATUS_FINAL))
                        $HTTP_BODY_NEW=$((HTTP_BODY_FINAL))
                        count=`expr $count + 1`
                            if [ $count -eq 0 ]
                            then   
                                break
                            else
                                continue
                            fi
                    done
                        echo "Starting the Jmeter Test" >> $LOG
            fi
}
for ip in ${IP_Addresses[@]}
do
    triggerPerformanceTest "$ip" &
done

让我知道它是否按您的预期工作。

echo消息将在/tmp/$iplist.log

(正在编辑...等待OP的回复)

答案2

最简单的解决方案是将循环移出函数并在后台运行该函数:

#!/bin/sh


triggerPerformanceTest(){ 
  thisIp=$1
  ## the rest of your tests. Just use $thisIp the way you were using
  ## the $iplist variable.
}

IP_Addresses="192.168.2.33,192.168.2.34,192.168.2.35"
for ip in $IP_Addresses; do
    triggerPerformanceTest "$ip" &
}

这将在每个 ip 上启动测试,并且由于您使用 向后台发送命令&,因此它们将在几乎同一时间。除非您需要毫秒精度,否则这应该足够了。

答案3

尽管您已经接受了答案。我想,你也可以通过使用parallel命令来实现这一点

#!/bin/sh

IP_Addresses=(192.168.2.33,192.168.2.34,192.168.2.35)

triggerPerformanceTest(){ 
    for iplist in $(echo $IP_Addresses | sed "s/,/ /g")
    do
        echo "Validating the health end point in the remote server"    
        HTTP_RESPONSE=$(curl -m 1800 --silent --write-out "HTTPSTATUS:%{http_code}" -X GET http://${iplist}:9096/health)
        HTTP_STATUS=$(echo $HTTP_RESPONSE | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
        HTTP_BODY=$(echo $HTTP_RESPONSE | sed -e 's/HTTPSTATUS\:.*//g')
            if [ $HTTP_STATUS -eq 200  ] && [ $HTTP_BODY = "OK" ]; then
                echo "Success!! it seems the health service is ruuning in the target machine"
                echo "Starting the Jmeter Test"
            else
                echo "The health end point of the nodejs service return exit code 1, let the service start on the remote host"
                sleep 20
                HTTP_RESPONSE_NEW=$(curl -m 1800 --silent --write-out "HTTPSTATUS:%{http_code}" -X GET http://${iplist}:9096/health)
                HTTP_STATUS_NEW=$(echo $HTTP_RESPONSE_NEW | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
                HTTP_BODY_NEW=$(echo $HTTP_RESPONSE_NEW | sed -e 's/HTTPSTATUS\:.*//g')
                count=2
                echo "Re-validating the health end point in the remote server"
                    while [ $HTTP_STATUS_NEW -ne 200 ] && [ $HTTP_BODY_NEW != "OK" ]
                    do
                        echo "Waiting for the Node-js service to start on the remote server"
                        sleep 5
                        HTTP_RESPONSE_FINAL=$(curl -m 1800 --silent --write-out "HTTPSTATUS:%{http_code}" -X GET http://${iplist}:9096/health)
                        HTTP_STATUS_FINAL=$(echo $HTTP_RESPONSE_NEW | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
                        HTTP_BODY_FINAL=$(echo $HTTP_RESPONSE_NEW | sed -e 's/HTTPSTATUS\:.*//g')

                        count=`expr $count + 1`
                            if [ $count -eq 0 ]
                            then   
                                break
                            else
                                continue
                            fi
                    done
                        echo "Starting the Jmeter Test"
            fi
    done
}

cat IP_Addresses_file | parallel triggerPerformanceTest {}

假设您有名为IP_Addresses_file包含所有 IP 地址的文件。

相关内容