스크립트 성능 향상 [닫기]

스크립트 성능 향상 [닫기]

저는 Zabbix 모니터링 서비스 실행이 중지되면 자동으로 다시 시작하는 데 사용할 수 있는 스크립트를 개발해 왔습니다. 내 스크립트는 잘 작동하지만 개선할 수 있다고 생각합니다.

#!/bin/bash
zabbix_server="service zabbix-server"
zabbix_agent="service zabbix-agent"
logfile=zabbix_auto_restart.log
logfilePath=/etc/scripts/zabbix/$logfile
zabbix_server_running=0
zabbix_agent_running=0

grep_agent (){
    local retval=$(ps -ef | grep -v grep | grep zabbix_agentd | wc -l)
    echo $retval
}

grep_server (){
    local retval=$(ps -ef | grep -v grep | grep zabbix_server | wc -l)
    echo $retval
}

check_zabbix_agentd (){
    if (( $(grep_agent) == 0 ))
    then
       $zabbix_agent start
       echo `date` "$zabbix_agent was stopped... Restarting" >> $logfile
       echo "************************************************" >> $logfile

       #Send email to notify that the script ran
       echo "$(date) $zabbix_agent was restarted from zabbix_restart.sh" | mutt -s "Zabbix Auto-restart Script Just Ran" <user email>

    else
       let zabbix_agent_running=1
    fi
}

check_zabbix_server (){
    if (( $(grep_server) == 0 ))
    then
       $zabbix_server start
       echo `date` "$zabbix_server was stopped... Restarting" >> $logfile
       echo "************************************************" >> $logfile

       #Send email to notify that the script ran
       echo "$(date) $zabbix_server was restarted from zabbix_restart.sh" | mutt -s "Zabbix Auto-restart Script Just Ran" <user email>

    else
       let zabbix_server_running=1
    fi
}

main_loop (){
    until ((zabbix_server_running == 1 && zabbix_agent_running == 1));
    do
        check_zabbix_agentd
        check_zabbix_server
        sleep 1.5
    done
}

main_loop

답변1

실제로 잘못하고 있는 것은 노력을 복제하는 것입니다. 기본적으로 _agent하드코딩된 모든 항목이 발생하거나 _server완전히 중복되는 것처럼 보입니다.

예를 들어 Linux 시스템에서 실행 중인 경우 이러한 grep_...()기능을 완전히 제거하고 두 check_...기능을 하나의 엔터티로 병합할 수 있습니다. 이는 다음과 같이 작동할 수 있습니다.

email(){ 
    mutt -s "Zabbix Auto-restart Script Just Ran" \<user email\>
}
prlog(){ 
    date +"%x %X:%tservice $1${2+%n************************}"
}
chk_run()
    while  [ "$#" -gt 0 ]
    do     if     ps -C zabbix_"$1"
           then   : "$(($1=1))"
           else   set zabbix_"$@"
                  service "$1" start || eval >&2 '
                  prlog   "$1 restart failed."  +; exit '"$?"
                  prlog   "$1 restarted."       +  >&2
                  prlog   "$1 restarted from $0." |email
           fi;    shift
    done

핵심은 chk_run매개변수 목록을 사용하여 호출을 수행한다는 것입니다. 각 구성원은 각 반복에 대해 확인해야 할 사항을 표시합니다.

loop()
    until [ "$(($1&&$2))" -eq 1 ]
    do    chk_run "$@"
          sleep 2
    done  >/dev/null 2>>"$log"
agentd=0 server=0 loop agentd server

POSIX에서 변경해야 할 유일한 것은 ps명령입니다. POSIX는 -C스위치를 지정하지 않기 때문입니다. 따라서 if이 줄을 다음과 같이 변경할 수 있습니다.

if    ps -eocomm= |
      grep -xqF zabbix_"$1"

최적화를 mutt제외 하고 표준 명령 언어여야 합니다.serviceps

표준 구문의 최소한 한 가지 장점은 #!/bin/bash해시뱅이 완전히 불필요하다는 것입니다. 여기에는 일부 쉘별 확장을 위한 앵커가 없으므로 POSIX 준수를 위해 노력하는 모든 쉘에서 거의 동일해야 합니다. 즉, #!/bin/dash매우 간단하다.(그리고 작동할 수도 있음)이 경우 최적화하십시오.

물론 최적화 여부에 관계없이 이 스크립트는 거의 항상 sleep.

나는 정의하기를 거부합니다 $log. 주로 당신이 그것을 정의하는 방식에 대해 말할 것이 없기 때문입니다. 그리고 그것은 괜찮습니다.생각하다더 이상 정의하지 마세요. 스크립트의 호출 환경을 결정할 수 있다면 인수를 전달하는 매우 간단한 방법이 될 수 있습니다. 즉, 스크립트가 호출되어 ./script이미 실행 가능하다면...

log=/dev/tty ./script

...호출될 때 환경에 값을 설정합니다 $log../script

/dev/tty출력 파일을 예로 사용하는 이유는 만족할 만큼 조정하면서 시작해야 한다고 생각하기 때문입니다. 여기에 코드 블록을 넣고 ./script위와 같이 실행하면 일부 출력 파일이 아닌 실시간으로 터미널에 기록되므로 실제 로그 파일에 어떤 내용이 나타날지 명확하게 알 수 있습니다. 결국 다음과 같이 호출합니다.

log=./real/logfile ./script

또는 하이브리드 동작으로 대신 다음과 같이 표시되도록 스크립트를 변경할 수 있습니다 2>>"$log".

2>>"${log:-/hardcoded/default/path/to/logfile}"

...이 경우 쉘은 $log아직 정의되지 않은 하드 코딩된 값을 사용합니다. 이는 다음을 의미합니다.

export log=/dev/tty; ./script
log=/dev/tty ./script

...계속해서 터미널에 로그 파일을 기록하고...

log= ./script
unset log; ./script

...하드코드된 경로에 쓰고...

./script

$log...현재 쉘 환경으로 내보내기 위해 널이 아닌 값이 이미 존재하는지 여부에 따라 하드코드된 경로나 다른 위치에 기록됩니다.

관련 정보