CPU / 메모리 사용량이 너무 높아지면 프로세스를 자동으로 종료하는 Bash 스크립트


11

CPU 및 / 또는 메모리 사용량이 80 %에 도달하면 프로세스를 종료하는 스크립트를 작성했습니다. 이 상황이 발생하면 종료 된 프로세스 목록이 작성됩니다. 개선하기 위해 무엇을 할 수 있습니까?

while [ 1 ];
do 
echo
echo checking for run-away process ...

CPU_USAGE=$(uptime | cut -d"," -f4 | cut -d":" -f2 | cut -d" " -f2 | sed -e "s/\.//g")
CPU_USAGE_THRESHOLD=800
PROCESS=$(ps aux r)
TOPPROCESS=$(ps -eo pid -eo pcpu -eo command | sort -k 2 -r | grep -v PID | head -n 1)

if [ $CPU_USAGE -gt $CPU_USAGE_THRESHOLD] ; then
  kill -9 $(ps -eo pid | sort -k 1 -r | grep -v PID | head -n 1) #original
  kill -9 $(ps -eo pcpu | sort -k 1 -r | grep -v %CPU | head -n 1)
  kill -9 $TOPPROCESS
  echo system overloading!
  echo Top-most process killed $TOPPROCESS
      echo CPU USAGE is at $CPU_LOAD

else
    fi
    exit 0
    sleep 1;
    done

3
스크립트를 실행 해 보셨습니까? while [ 1 ]이 스크립트만으로도 CPU 사용량이 궁금합니다. 또한 kill -9지속적으로 실행되는 스크립트에서 3 번의 호출이 있습니까? 이것은 나에게 오한을 준다 ...
rahmu

1
어쨌든 멋진 아바타, @rahmu 그는 sleep 1루프에 있어
데이지

1
매월 첫 번째 월요일과 PC에서 (느린) RAID6 세트를 확인하고 있습니다. CPU로드는이 RAID 세트에서 디스크 IO를 지속적으로 기다리고 있기 때문에 8을 초과하는 경우가 많습니다. 잘못된 것은 아니지만 시스템은 여전히 ​​매우 반응이 빠릅니다. 귀하의 스크립트는 사용 가능한 400 %의 3.6 % 만 사용하는 파이어 폭스를 죽일 것입니다. 이 스크립트를 사용하여 유령을 사냥하고 있다고 말할 수 있습니다. BTW : 높은로드로 인해 시스템이 손상되지 않으며 메모리가 부족할 때 커널은 어느 프로세스 (들)를 죽일 지에 대한 반 교육적인 추측을합니다.
jippie

그런 다음 기반로드에서 킬 프로세스가 양호합니까 ???
Ketan Patel

내 유스 케이스에서 살해는 바람직하지 않습니다.
jippie

답변:


11

추측 당신이 해결하려는 문제가 당신이 당신의 상자 때로는 무례한 행동에 대한 몇 가지 실행중인 프로세스를 가지고있다, 영원히 코어를 동격 앉아있다.

가장 먼저해야 할 일은 미쳐가는 프로그램을 수정하는 것입니다. 그것은 지금까지 최고의 솔루션입니다. 나는 그것이 불가능하다고 가정하거나 상자가 고정 될 때까지 상자를 계속 작동시키기 위해 빠른 kluge가 필요합니다.

최소한 하나의 관심있는 프로그램 만 스크립트가 실행되도록 제한하려고합니다. 권한이 이와 같이 스크립트를 제한 한 경우가 가장 좋습니다 (예 : 스크립트가 사용자 X로 실행되고 X로 실행되는 유일한 것은 프로그램 임).

ulimit -t프로그램이 사용할 수있는 총 CPU 시간을 제한하는 것과 같은 것을 사용하는 것이 더 좋습니다 . 마찬가지로 모든 메모리를 사용하는 경우 확인하십시오 ulimit -v. 커널은 이러한 제한을 시행합니다. 자세한 내용은 bash맨 페이지 (쉘 내장) 및 setrlimit(2)맨 페이지를 참조하십시오.

문제가 진행중인 프로세스가 아니라 너무 많은 프로세스를 실행하는 경우 X 이상의 실행을 막기 위해 일종의 잠금 방식을 구현하십시오 (또는 익숙해 져야합니다 ulimit -u). 해당 프로세스의 스케줄러 우선 순위를 변경 ( nice또는 사용) 하거나 정책을로 변경 renice하여보다 과감하게 고려할 수도 있습니다 .sched_setschedulerSCHED_IDLE

더 많은 제어가 필요한 경우 제어 그룹 (cgroup)을 살펴보십시오. 실행중인 커널에 따라 전체 프로세스 그룹이 함께 소비하는 CPU 시간, 메모리, I / O 등의 양을 실제로 제한 할 수 있습니다. 컨트롤 그룹은 매우 유연합니다. 그들은 깨지기 쉬운 kluges없이 당신이하려는 무엇이든 할 수 있습니다. Arch Linux Wiki에는 LWN 의 Neil Brown의 cgroup 시리즈 와 마찬가지로 읽을 가치가있는 cgroup에 대한 소개가 있습니다.


3

이슈 :

  • 숫자 필드를 정렬 할 때 -n옵션 을 사용하고 싶을 것입니다 sort -nrk 2. 그렇지 않으면 %CPU값이 5.0 인 줄 은 값이 12.0 인 줄보다 더 높아집니다.
  • ps구현 에 따라 --no-headers옵션을 사용 하여을 제거 할 수 grep -v있습니다. 그러면가 포함 된 명령을 버릴 수 없습니다 PID.
  • 대신에 echo CPU USAGE is at $CPU_LOAD당신이 의미 하는 것 같아요 echo CPU USAGE is at $CPU_USAGE.
  • exit 0디버깅 중에 삽입 한 것을 제거하는 것을 잊었을 것 같습니다 (?).

스타일:

  • CPU_USAGE_THRESHOLD=800가장 유용한 정보이며 스크립트가 안정된 후에도 변경 될 가능성이 높으므로 행을 파일의 시작 부분 으로 이동하려고 할 수 있습니다 .
  • -e옵션을 반복합니다 : ps -eo pid -eo pcpu -eo commandps -eo pid -o pcpu -o command(와 ps -eo pid,pcpu,command) 동일 합니다.
  • else절이 있습니다. 그것은 항상 처리되어야하는 것처럼 보이지만 알 수없는 이유는 아닙니다.

2

대부분의 CPU / 메모리를 사용하는 프로세스를 종료하는 데 문제가 있습니다. 현재 시스템에있는 프로세스 (여기서는 firefox, systemd (init), Xorg, gnome-terminal, 일련의 커널 스레드, xemacs)를 확인하십시오. 어느 것도 필수 불가결합니다). 예를 들어, 리눅스의 OOM 킬러을 조정할하는 방법 좀 봐 여기 .

또한 "프로세스가 사용하는 메모리"는 공유 라이브러리가 있고 실행 파일이 공유되며 심지어 데이터 영역의 일부이기 때문에 훌륭한 개념입니다. 각 사용자에게 사용 된 공간의 일부를 충전하여 숫자를 얻을 수 있지만 추가해도 실제로 "사용 된 메모리"를 제공하지 않습니다 ( "프로세스가 사라지면 사용 가능한 메모리가 적음"). 뒤에).


1

CPU 사용량이 YY 초 동안 XX %보다 크거나 ZZ 초 이상 실행되는 프로세스를 종료하는 경우 배열에 나열된 일부 프로세스를 종료하는 kill-process 스크립트를 작성했습니다 .

  • 파일 상단에 XX, YY, ZZ를 설정할 수 있습니다.
  • 점검 프로세스에 ps 또는 top을 사용할 수 있습니다.
  • 건식 실행 모드도 있습니다.
  • 결국, 일부 프로세스가 종료되면 스크립트가 이메일을 보냅니다.

참고 : 여기 Github에 대한 레포가 있습니다 : https://github.com/padosoft/kill-process

스크린 샷은 다음과 같습니다.

         ss # 1

참고 문헌

스크립트의 필수 부분 (최상위 명령을위한 코드 요약) :

#!/usr/bin/env bash

#max cpu % load
MAX_CPU=90
#max execution time for CPU percentage > MAX_CPU (in seconds 7200s=2h)
MAX_SEC=1800
#sort by cpu
SORTBY=9

#define a processes command name to check
declare -a KILLLIST
KILLLIST=("/usr/sbin/apache2" "/usr/bin/php5-cgi")

#iterate for each process to check in list
for PROCESS_TOCHECK in ${KILLLIST[*]}
do

    #retrive pid with top command order by SORTBY
    PID=$(top -bcSH -n 1 | grep $PROCESS_TOCHECK | sort -k $SORTBY -r | head -n 1 | awk '{print $1}')

    CPU=$(top -p $PID -bcSH -n 1 | grep $PROCESS_TOCHECK | sort -k $SORTBY -r | head -n 1 | awk '{print $9}')
    TIME_STR=$(top -p $PID -bcSH -n 1 | grep $PROCESS_TOCHECK | sort -k $SORTBY -r | head -n 1 | awk '{print $11}')

    # Decode the top CPU time format [dd-]hh:mm.ss.
    TIME_SEC=0
    IFS="-:" read c1 c2 c3 c4 <<< "$TIME_STR"

    #with top command time format is hh:mm.ss, so truncare seconds in c2
    c2=${c2%%.*}

    if [ -n "$c4" ]
    then
      TIME_SEC=$((10#$c4+60*(10#$c3+60*(10#$c2+24*10#$c1))))
    elif [ -n "$c3" ]
    then
      if [ "$CMD" = "ps" ]; then
        TIME_SEC=$((10#$c3+60*(10#$c2+60*10#$c1)))
      else
        TIME_SEC=$(((10#$c3*24)*60*60)+60*(10#$c2+60*10#$c1))             
      fi   
    else
      if [ "$CMD" = "ps" ]; then
        TIME_SEC=$((10#0+(10#$c2+60*10#$c1)))
      else
        TIME_SEC=$((10#0+60*(10#$c2+60*10#$c1)))
      fi
    fi

    #check if need to kill process
    if [ $CPU -gt $MAX_CPU ] && [ $TIME_SEC -gt $MAX_SEC ]; then
        kill -15 $PID
    fi

done
용법:
bash killprocess.sh [dry|kill|--help] [top|ps] [cpu|time]

보인다 sort해야한다 sort -k9nr. 가 없으면 n`5.9`>가 29.4됩니다.
lk_vc
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.