シェルスクリプトでサーバーURLを実行するときに再試行メカニズムを実装する方法は?

シェルスクリプトでサーバーURLを実行するときに再試行メカニズムを実装する方法は?

私はbashシェルスクリプトで私のサーバーの1つに対してURL呼び出しを実行する必要があるプロジェクトを進めています。

http://hostname.domain.com:8080/beat

上記のURLをクリックすると、次の応答が表示され、それを解析してsyncs値を抽出する必要があります。syncs_behind

state: READY process: 30 process_behind: 100 num_rounds: 60 hour_col: 2 day_col: 0 oldest_day_col: 0

10分間で10秒ごとに上記のURLを入力してからprocess合計値を抽出し、process_behindそれを使用して次の条件で検証する必要があります。

process > 8
process_behind = 0

syncが8より大きく、process_behind = 0の場合は、「データ検証済み」というメッセージでシェルスクリプトを終了し、それ以外の場合は10分間続行します。 10分以内に上記の条件が満たされない場合は、シェルスクリプトを終了します。言い換えれば、再試行しません。

以下は、上記のタスクを実行し、サーバーの起動時に通常の状況でうまく機能するシェルスクリプトです。

#!/bin/bash

COUNT=60   #number of 10 second timeouts in 10 minutes

while [[ $COUNT -ge "0" ]]; do

#send the request, put response in variable
DATA=$(wget -O - -q -t 1 http://hostname.domain.com:8080/beat)

#grep $DATA for process and process_behind
PROCESS=$(echo $DATA | grep -oE 'process: [0-9]+' | awk '{print $2}')
PROCESS_BEHIND=$(echo $DATA | grep -oE 'process_behind: [0-9]+' | awk '{print $2}')

echo $PROCESS
echo $PROCESS_BEHIND

#verify conditionals
if [[ $PROCESS -gt "8" && $PROCESS_BEHIND -eq "0" ]]; then exit 0; fi

#decrement the counter
let COUNT-=1

#wait another 10 seconds
sleep 10

done

サーバーがダウンしているとエラーが発生し、その行でwget例外が発生したとします。

今やりたいことは、サーバーがダウンしている場合は30秒間スリープモードを維持し、サーバーURLの実行を再試行し、失敗した場合は30秒間スリープモードに戻してサーバーURLの実行を再試行することです。 nが10であるとし、サーバーURLをn回実行しましょう。

その後も、サーバーはまだ起動せず、ゼロ以外の状態でシェルスクリプトを終了し、メッセージサーバーがダウンしました。ただし、サーバーが稼働していて応答を受信できる場合は、後でシェルスクリプトからそのフィールドを引き続き抽出します。

Bashシェルスクリプトで再試行メカニズムを実装できますか?それともwget以外に良い方法がありますか?

アップデート 1:-

これが私が得たものです -

#!/bin/bash

COUNT=60   #number of 10 second timeouts in 10 minutes
DATA=""
RETRY=10

while [[ $COUNT -ge "0" ]]; do

while [ $RETRY -gt 0 ]
do
    #send the request, put response in variable
    DATA=$(wget -O - -q -t 1 http://machineA:8080/beat)
    echo "Hello"
    if [ $? -eq 0 ]
    then
        break
    else
        let RETRY-=1
        sleep 30
    fi
done

if [ $RETRY -eq 0 ]
then
    exit 2
fi

#grep $DATA for process and process_behind
PROCESS=$(echo $DATA | grep -oE 'process: [0-9]+' | awk '{print $2}')
PROCESS_BEHIND=$(echo $DATA | grep -oE 'process_behind: [0-9]+' | awk '{print $2}')

echo $PROCESS
echo $PROCESS_BEHIND

#verify conditionals
if [[ $PROCESS -gt "8" && $PROCESS_BEHIND -eq "0" ]]; then exit 0; fi

#decrement the counter
let COUNT-=1

#wait another 10 seconds
sleep 10

done

サーバーがダウンして上記のシェルスクリプトを実行している場合は、コンソールに「Hello」と印刷され、正常に動作します。しかし、以下の私のアップデートをご覧ください。

アップデート 2:-

さて、今問題を見つけました。このようなシェルスクリプトを実行すると、本番システムで実行され、サーバーがダウンしても「Hello」はまったく印刷されません。しかし、アップデート1で上記のシェルスクリプトを実行しましたが、サーバーがダウンした場合は正常に動作します。

#!/bin/bash

COUNT=60   #number of 10 second timeouts in 10 minutes
HOSTNAME=machineA
DATA=""
RETRY=10

while [[ $COUNT -ge "0" ]]; do

while [ $RETRY -gt 0 ]
do
    #send the request, put response in variable
    DATA=$(wget -O - -q -t 1 http://$HOSTNAME:8080/beat)
    echo "Hello"
    if [ $? -eq 0 ]
    then
        break
    else
        let RETRY-=1
        sleep 30
    fi
done

if [ $RETRY -eq 0 ]
then
    exit 2
fi

#grep $DATA for process and process_behind
PROCESS=$(echo $DATA | grep -oE 'process: [0-9]+' | awk '{print $2}')
PROCESS_BEHIND=$(echo $DATA | grep -oE 'process_behind: [0-9]+' | awk '{print $2}')

echo $PROCESS
echo $PROCESS_BEHIND

#verify conditionals
if [[ $PROCESS -gt "8" && $PROCESS_BEHIND -eq "0" ]]; then exit 0; fi

#decrement the counter
let COUNT-=1

#wait another 10 seconds
sleep 10

done

上記のスクリプトを使用してデバッグモードで取得した結果は次のとおりです。

david@some-machine:~$ bash -x ./ping1.sh
+ set -e
+ COUNT=60
+ HOSTNAME=machineA
+ DATA=
+ RETRY=10
+ echo machineA
machineA
+ [[ 60 -ge 0 ]]
+ '[' 10 -gt 0 ']'
++ wget -O - -q -t 1 http://machineA:8080/beat
+ DATA=

これらの2つのスクリプトは同じだと思いますか?それでは、なぜこれが起こるのですか?

答え1

簡単なループを使用できます。

....
DATA=""
RETRY=10

while [ "$RETRY" -gt 0 ]; do
  DATA="$(wget -O - -q -t 1 http://hostname.domain.com:8080/beat)"
  if [ $? -eq 0 ]
  then
    break
  else
    let RETRY-=1
    sleep 30
  fi
done

if [ "$RETRY" -eq 0 ]
then
  exit 2
fi
....

関連情報