쉘 스크립트에서 서버 URL을 실행할 때 재시도 메커니즘을 구현하는 방법은 무엇입니까?

쉘 스크립트에서 서버 URL을 실행할 때 재시도 메커니즘을 구현하는 방법은 무엇입니까?

저는 bash 쉘 스크립트에서 내 서버 중 하나에 대한 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번 실행해 보겠습니다.

그 후에도 서버가 여전히 시작되지 않고 0이 아닌 상태로 쉘 스크립트를 종료하고 메시지 서버가 다운되었습니다. 그러나 서버가 작동 중이고 응답을 받을 수 있으면 나중에 쉘 스크립트에서 해당 필드를 계속 추출하겠습니다.

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=

이 두 스크립트가 같은 것 같아요? 그렇다면 왜 이런 일이 발생합니까?

답변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
....

관련 정보