सीपीयू / मेमोरी उपयोग बहुत अधिक होने पर स्वचालित रूप से प्रक्रियाओं को मारता है कि बैश स्क्रिप्ट


11

मैंने एक स्क्रिप्ट बनाई है जो सीपीयू और / या मेमोरी उपयोग 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 ]मुझे आश्चर्य है कि अकेले इस स्क्रिप्ट का कितना सीपीयू उपभोग करने वाला है। इसके अलावा, kill -9लगातार चलने वाली स्क्रिप्ट में 3 कॉल ? इससे मुझे ठंड लग रही है ...
rahmu

1
वैसे भी अच्छा अवतार, @ प्रहमु को वह sleep 1पाश में मिला
daisy

1
महीने का पहला सोमवार और मेरा पीसी एक (धीमी) RAID6 सेट की जाँच कर रहा है। सीपीयू लोड आसानी से 8 से ऊपर चोटियों पर आता है क्योंकि यह इस RAID सेट से डिस्क IO की लगातार प्रतीक्षा कर रहा है। कुछ भी गलत नहीं है, सिस्टम अभी भी बहुत संवेदनशील है। आपकी स्क्रिप्ट मेरे फ़ायरफ़ॉक्स को मार देगी जो उपलब्ध 400% में से केवल 3.6% का उपयोग करता है। सिर्फ यह कहकर कि आप इस स्क्रिप्ट के साथ भूतों के शिकार हो सकते हैं। BTW: उच्च लोड के कारण आपका सिस्टम खराब नहीं होगा और जब मेमोरी चलेगी, तो कर्नेल एक अर्ध-शिक्षित अनुमान लगाएगा कि किस प्रक्रिया (एस) को मारने के लिए।
जिप्पी

फिर आधारित लोड पर मार प्रक्रिया ठीक होगी या नहीं ????
केतन पटेल

मेरे उपयोग के मामले में हत्या वांछित नहीं है।
जिप्पी

जवाबों:


11

मैं अनुमान लगा रहा हूं कि आप जिस समस्या को हल करना चाहते हैं, वह यह है कि आपके बॉक्स पर कुछ प्रक्रिया चल रही है जो कभी-कभी गलत व्यवहार करती है, और हमेशा एक कोर को पेग करते हुए बैठती है।

पहली चीज जो आप करना चाहते हैं, वह उस कार्यक्रम को ठीक करने का प्रयास करना है जो पागल हो जाता है। यह अब तक का सबसे अच्छा समाधान है। मैं मान रहा हूँ कि यह संभव नहीं है, या आपको अपने बॉक्स को उसके नियत समय तक चालू रखने के लिए एक त्वरित kluge की आवश्यकता है।

आप कम से कम, अपनी स्क्रिप्ट को केवल उस प्रोग्राम को हिट करने के लिए सीमित करना चाहते हैं जिस पर आप चिंतित हैं। यह सबसे अच्छा होगा यदि अनुमतियाँ आपकी स्क्रिप्ट को इस तरह सीमित करें (जैसे, आपकी स्क्रिप्ट उपयोगकर्ता एक्स के रूप में चलती है, एक्स के रूप में चलने वाली एकमात्र अन्य चीज प्रोग्राम है)।

इससे भी बेहतर यह होगा ulimit -tकि प्रोग्राम के उपयोग के लिए कुल सीपीयू समय की मात्रा को सीमित करने के लिए कुछ का उपयोग किया जाए। इसी तरह, यदि यह सभी मेमोरी का उपभोग करता है, तो जांच करें ulimit -v। कर्नेल इन सीमाओं को लागू करता है; विवरण के लिए bashमैनपेज (यह एक शेल निर्मित है) और setrlimit(2)मैनपेज देखें।

यदि समस्या एमोक चलाने की प्रक्रिया नहीं है, लेकिन इसके बजाय बस बहुत सी प्रक्रियाएं चल रही हैं, तो एक्स को चलाने से अधिक रोकने के लिए लॉकिंग के कुछ रूप को लागू करें (या - यह परिचित होना चाहिए- ulimit -u)। आप उन प्रक्रियाओं के शेड्यूलर प्राथमिकता को बदलने (उपयोग करने niceया renice), या इससे भी अधिक कठोर के लिए, sched_setschedulerनीति को बदलने के लिए उपयोग करने पर विचार कर सकते हैं SCHED_IDLE

यदि आपको और भी अधिक नियंत्रण की आवश्यकता है, तो एक नियंत्रण समूह (cgroups) पर एक नज़र डालें। आपके द्वारा चलाए जा रहे कर्नेल के आधार पर, आप वास्तव में CPU समय, मेमोरी, I / O इत्यादि की मात्रा को सीमित कर सकते हैं, जो कि प्रक्रियाओं का एक पूरा समूह उपभोग करता है। नियंत्रण समूह काफी लचीले होते हैं; वे संभावना कर सकते हैं कि आप जो भी करने की कोशिश कर रहे हैं, बिना किसी नाजुक कलगी के। आर्क लिनक्स विकी में cgroups के लिए एक परिचय है जो पढ़ने के लायक है, जैसा कि नील ब्राउन के Lg में cgroups श्रृंखला है


3

मुद्दे:

  • सांख्यिक क्षेत्र छाँटने के दौरान आप शायद -nविकल्प का उपयोग करना चाहते हैं sort -nrk 2:। अन्यथा %CPU5.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 commandजैसा ps -eo pid -o pcpu -o command(जैसा है ps -eo pid,pcpu,command) वैसा ही है ।
  • एक खाली elseखंड है। यह हमेशा ऐसा लगता है जैसे इसे संभाला जाना चाहिए, लेकिन किसी अज्ञात कारण से नहीं था।

2

उन प्रक्रियाओं को मारना, जो अधिकांश सीपीयू / मेमोरी का उपयोग कर रहे हैं, मुसीबत के लिए पूछ रहे हैं: बस देखो कि वे अभी आपकी मशीन पर क्या कर रहे हैं (यहाँ वर्तमान में फ़ायरफ़ॉक्स, सिस्टमड (init), Xorg, सूक्ति-टर्मिनल, कर्नेल थ्रेड्स का एक सेट, xemacs; जिसमें से कोई भी डिस्पेंसबल नहीं है)। कैसे लिनक्स 'OOM-हत्यारा बदलाव करने, उदाहरण के लिए को देखो यहाँ

यह भी ध्यान दें कि "मेमोरी द्वारा उपयोग की जाने वाली प्रक्रिया" एक अस्पष्ट अवधारणा है, क्योंकि साझा लाइब्रेरी हैं, निष्पादन योग्य साझा हैं, और यहां तक ​​कि डेटा क्षेत्रों के हिस्से भी हैं। प्रत्येक उपयोगकर्ता को उपयोग किए गए स्थान के एक अंश के साथ चार्ज करके कुछ संख्या के साथ आ सकता है, लेकिन यहां तक ​​कि जोड़कर वास्तव में "मेमोरी का उपयोग नहीं किया जाता है" (इससे भी कम "स्मृति मुक्त हो जाती है अगर प्रक्रिया चली जाती है", तो साझा किए गए हिस्से पीछे)।


1

मैंने एक स्क्रिप्ट, किल-प्रक्रिया बनाई है , जो एक सरणी में सूचीबद्ध कुछ प्रक्रियाओं को मारता है, अगर CPU उपयोग YY सेकंड के लिए XX% से अधिक है या ZZ सेकंड से अधिक चलने वाली प्रक्रियाओं को मार सकता है।

  • आप फ़ाइल के शीर्ष में XX, YY, ZZ सेट कर सकते हैं।
  • आप चेक प्रक्रियाओं के लिए पीएस या शीर्ष का उपयोग कर सकते हैं।
  • एक सूखी रन मोड भी है, जांच करने के लिए लेकिन मार नहीं।
  • अंत में, स्क्रिप्ट एक ईमेल भेजती है अगर कुछ प्रक्रियाएं मार दी गईं।

नोट: यहाँ Github पर मेरा रेपो है: https://github.com/padosoft/kill-process

यहाँ एक स्क्रीनशॉट है:

         एस एस # 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
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.