메모리 사용량 테스트용 스크립트 [닫기]

메모리 사용량 테스트용 스크립트 [닫기]

애플리케이션 메모리 누수에 대한 해결책을 찾는 동안 임시 반창고를 붙이려고 합니다. 내가 작성한 것은 작은 bash스크립트로 서버의 루트 디렉터리에 위치합니다. 스크립트가 수행해야 하는 작업은 다음과 같습니다.

  1. 실행 중인 위치를 가져옵니다.
  2. 스크립트가 crontab인지 확인
  3. crontab에 없으면 crontab에 추가하여 5분마다 실행합니다.
  4. 메모리를 테스트하고 %가 Percentage_allowed보다 높은지 확인하세요.
  5. 위 테스트가 완료되면 nginx 및 php-fmp 서비스를 다시 시작하세요.

memory_protect.sh:

#!/bin/sh
cronfile=memory_protect.sh    #NOTE THIS SHOULD DETECT IT'S SELF
path=pwd                      #this is the path to the file 
percent_allowed=80            #this should be max memory before action

has_cron(){
    #is the file in the cron?
    return [[ crontab -l | egrep -v '^$|^#' | grep -q $cronfile ]] && return 1 || return 0
}
test_memory(){
    memusage=`top -n 1 -b | grep "Mem"`
    MAXMEM=`echo $memusage | cut -d" " -f2 | awk '{print substr($0,1,length($0)-1)}'`
    USEDMEM=`echo $memusage | cut -d" " -f4 | awk '{print substr($0,1,length($0)-1)}'`

    USEDMEM1=`expr $USEDMEM \* 100`
    PERCENTAGE=`expr $USEDMEM1 / $MAXMEM`
    #if it's above 80% alert
    return [[ $PERCENTAG>$percent_allowed ]] && return 1 || return 0
}

if [[ has_cron -eq 0 ]]
then
    #was not here so add
    #run this script every 5 mins
    */5 * * * $path/$cronfile
fi

if [[ test_memory ]]
then
    #clear some memory
    /etc/init.d/nginx restart
    /etc/init.d/php-fpm restart
fi

메모리 테스트를 자체적으로 실행해 보면 잘 되는 것 같은데, 이건 안되는 것 같습니다.


고쳐 쓰다dos2unix파일에서 실행 해야 하지만 결국에는 각 함수의 조건에 대한 반환이 발생한다는 것도 깨달았습니다. 따라서 이 방법은 작동하지 않습니다. 이제 해당 문을 찾을 수 없는 것 같습니다 [[.if


업데이트 2 자세히 보면 서비스를 다시 시작하는 중이지만 cron 작업을 넣지 않아서 실행 중인 것이 보이지 않습니다.

#!/bin/bash
cronfile=memory_protect.sh    #NOTE THIS SHOULD DETECT IT'S SELF
path=pwd                      #this is the path to the file 
percent_allowed=80            #this should be max memory before action

has_cron(){
    #is the file in the cron?
    #return 0 #returning this just to test should
    #be the next line but it's not working
    return 0
    [[ crontab -l | egrep -v '^$|^#' | grep -q $cronfile ]] && return 1 || return 0
}
test_memory(){
    memusage=`top -n 1 -b | grep "Mem"`
    MAXMEM=`echo $memusage | cut -d" " -f2 | awk '{print substr($0,1,length($0)-1)}'`
    USEDMEM=`echo $memusage | cut -d" " -f4 | awk '{print substr($0,1,length($0)-1)}'`

    USEDMEM1=`expr $USEDMEM \* 100`
    PERCENTAGE=`expr $USEDMEM1 / $MAXMEM`
    #if it's above 80% alert
    [[ $PERCENTAG -gt $percent_allowed ]] && return 1 || return 0
}

if [[ has_cron -eq 0 ]]
then
    #was not here so add
    #run this script every 5 mins
    #crontab -e */5 * * * $path/$cronfile
    cat <(crontab -l) <(echo "*/5 * * * $path/$cronfile") | crontab -
else
    echo "cron present"
fi

if [ test_memory ]
then
    #clear some memory
    sudo /etc/init.d/nginx restart
    sudo /etc/init.d/php-fpm restart
fi

이제 거의 수정이 된 것 같아요.

답변1

Bash 스크립트를 통해 crontab 항목을 생성하려면 다음 줄을 변경해야 합니다.

*/5 * * * * $path/$cronfile

다음과 같은 경우:

# Write out current crontab
crontab -l > mycron

# Echo new cron into cron file
echo "*/5 * * * * $path/$cronfile" >> mycron

# Install new cron file
crontab mycron
rm mycron

이 라이너를 사용하여 모든 작업을 수행할 수도 있습니다.

cat <(crontab -l) <(echo "*/5 * * * $path/$cronfile") | crontab -

당신의 스크립트

다음은 나를 위해 일한 수정된 스크립트 버전입니다.

#!/bin/sh

cronfile=memory_protect.sh    #NOTE THIS SHOULD DETECT IT'S SELF
path=$(pwd)                   #this is the path to the file 
percent_allowed=80            #this should be max memory before action

has_cron(){
    #is the file in the cron?
    #return 0 #returning this just to test should
    #be the next line but it's not working
    if crontab -l | egrep -v '^$|^#' | grep -q $cronfile; then
      return 1
    else
      return 0
    fi
}
test_memory(){
    memusage=$(top -n 1 -b | grep "Mem")
    MAXMEM=$(echo $memusage | cut -d" " -f2 | awk '{print substr($0,1,length($0)-1)}')
    USEDMEM=$(echo $memusage | cut -d" " -f4 | awk '{print substr($0,1,length($0)-1)}')

    USEDMEM1=$(expr $USEDMEM \* 100)
    PERCENTAGE=$(expr $USEDMEM1 / $MAXMEM)
    #if it's above 80% alert
    [[ $PERCENTAG>$percent_allowed ]] && return 1 || return 0
}

if has_cron;
then
    #was not here so add
    #run this script every 5 mins
    #crontab -e */5 * * * $path/$cronfile
    #cat <(crontab -l) <(echo "*/5 * * * $path/$cronfile") | crontab -
    crontab -l > mycron

    # Echo new cron into cron file
    echo "*/5 * * * * $path/$cronfile" >> mycron

    # Install new cron file
    crontab mycron
    rm mycron
else
    echo "cron present"
fi

if test_memory;
then
    #clear some memory
    echo "/etc/init.d/nginx restart"
    echo "/etc/init.d/php-fpm restart"
fi

$ ./memory_protect.sh 
/etc/init.d/nginx restart
/etc/init.d/php-fpm restart

$ crontab -l
*/5 * * * * /home/saml/tst/91789/memory_protect.sh

nginx스크립트가 실제로 다시 시작 되고 서비스 되도록 하려면 이 두 줄을 수정해야 합니다 php-fpm.

다음 줄을 변경하세요: echo "/etc/init.d/nginx restart" echo "/etc/init.d/php-fpm restart"

이것들을 위해:

    /etc/init.d/nginx restart
    /etc/init.d/php-fpm restart

스크립트가 올바르게 실행되는지 확인하기 위해 이 작업을 수행합니다. 참고: sudo이 스크립트를 루트가 아닌 다른 사용자로 실행하는 경우 이러한 다시 시작 줄 앞에 !

        sudo /etc/init.d/nginx 재시작 sudo /etc/init.d/php-fpm 재시작

이를 사용하려면 NOPASSWD두 스크립트 모두에 대한 최소한의 권한이 필요할 수 있습니다. 그렇지 않으면 cron을 소유한 사용자가 비밀번호를 제공할 때까지 기다립니다.

crontab 항목이 존재하지 않습니까?

crontab이 디렉토리에 생성되지 않은 경우 이 문제가 발생합니다 /var/sppol/cron. 다음과 같이 실행 하면 이 문제가 발생합니다 crontab -l.

$ crontab -l
no crontab for saml

다시 확인하세요:

$ sudo ls -l /var/spool/cron/
total 0
-rw------- 1 root root 0 Sep 16 23:47 root

따라서 간단히 편집하고 빈 파일을 저장하여 생성한다고 가정합니다.

$ crontab -e

# now you're in the vim editor, add a empty line
# type "i", hit return, hit Escape,
# and do a Shift + Z + Z to save!

이제 다음이 표시됩니다.

$ crontab -l
$ 

이:

$ sudo ls -l /var/spool/cron/
total 0
-rw------- 1 root root 0 Sep 16 23:47 root
-rw------- 1 saml root 0 Sep 21 16:20 saml

서비스 다시 시작

직면하게 될 또 다른 문제는 이 crontab 항목이 user1 사용자로 실행되는 경우 user1이 sudo이를 다시 시작하려면 권한이 필요하다는 것입니다.

답변2

나는 사용할 것이다감시 장치이를 위해

귀하의 요구 사항에 대한 monit 스크립트 예는 다음과 같습니다.

check process nginx with pidfile /var/run/nginx.pid
  start program = "/etc/init.d/nginx start"
  stop program  = "/etc/init.d/nginx stop"
  if memory usage > 95% then restart
  group www-data 
  if 5 restarts within 5 cycles then timeout 

5번 다시 시작을 시도했습니다. 모니터가 실패하면 경합 상태를 피하기 위해 웹 서버를 5번 다시 시작했습니다.

참고 링크

관련 정보