Kaynağa Gözat

Limit CPU usage

Bob Mottram 11 yıl önce
ebeveyn
işleme
79e689061e
1 değiştirilmiş dosya ile 140 ekleme ve 0 silme
  1. 140
    0
      beaglebone.txt

+ 140
- 0
beaglebone.txt Dosyayı Görüntüle

@@ -874,6 +874,146 @@ and check that some number of bits are set within a 4096 bit sized key:
874 874
 debug2: bits set: */4096
875 875
 #+END_SRC
876 876
 
877
+** Install CPU limiter
878
+
879
+#+BEGIN_VERSE
880
+/On every side, and at every hour of the day, we came up against the relentless limitations of pioneer life./
881
+
882
+-- Anna Howard Shaw
883
+#+END_VERSE
884
+
885
+Some process may consume a lot of CPU power and cause the system to become unresponsive or to crash.  To avoid that it's possible to limit the maximum percentage of the CPU which processes can use. We can whitelist some editors and tools that are commonly used and which have an initial CPU spike (such as Emacs loading its configuration files), with everything else being subject to a CPU limit if usage goes above a threshold percentage for more than one second.
886
+
887
+#+BEGIN_SRC: bash
888
+apt-get install cpulimit gawk
889
+#+END_SRC
890
+
891
+Create a script which can be run as a daemon.
892
+
893
+#+BEGIN_SRC: bash
894
+editor /usr/bin/cpulimit_daemon.sh
895
+#+END_SRC
896
+
897
+Add the following:
898
+
899
+#+BEGIN_SRC: bash
900
+#!/bin/bash
901
+# ==============================================================
902
+# CPU limit daemon - set PID's max. percentage CPU consumptions
903
+# ==============================================================
904
+
905
+# Variables
906
+CPU_LIMIT=20            # Maximum percentage CPU consumption by each PID
907
+DAEMON_INTERVAL=1       # Daemon check interval in seconds
908
+BLACK_PROCESSES_LIST=   # Limit only processes defined in this variable. If variable is empty (default) all violating processes are limited.
909
+WHITE_PROCESSES_LIST="cron|top|emacs|vi|vim|nano"   # Limit all processes except processes defined in this variable. If variable is empty (default) all violating processes are limited.
910
+
911
+# Check if one of the variables BLACK_PROCESSES_LIST or WHITE_PROCESSES_LIST is defined.
912
+if [[ -n "$BLACK_PROCESSES_LIST" &&  -n "$WHITE_PROCESSES_LIST" ]] ; then    # If both variables are defined then error is produced.
913
+   echo "At least one or both of the variables BLACK_PROCESSES_LIST or WHITE_PROCESSES_LIST must be empty."
914
+   exit 1
915
+elif [[ -n "$BLACK_PROCESSES_LIST" ]] ; then                                 # If this variable is non-empty then set NEW_PIDS_COMMAND variable to bellow command
916
+   NEW_PIDS_COMMAND="top -b -n1 -c | grep -E '$BLACK_PROCESSES_LIST' | gawk '\$9>CPU_LIMIT {print \$1}' CPU_LIMIT=$CPU_LIMIT"
917
+elif [[ -n "$WHITE_PROCESSES_LIST" ]] ; then                                 # If this variable is non-empty then set NEW_PIDS_COMMAND variable to bellow command
918
+   NEW_PIDS_COMMAND="top -b -n1 -c | gawk 'NR>6' | grep -E -v '$WHITE_PROCESSES_LIST' | gawk '\$9>CPU_LIMIT {print \$1}' CPU_LIMIT=$CPU_LIMIT"
919
+else
920
+   NEW_PIDS_COMMAND="top -b -n1 -c | gawk 'NR>6 && \$9>CPU_LIMIT {print \$1}' CPU_LIMIT=$CPU_LIMIT"
921
+fi
922
+
923
+# Search and limit violating PIDs
924
+while sleep $DAEMON_INTERVAL
925
+do
926
+   NEW_PIDS=$(eval "$NEW_PIDS_COMMAND")                                                                    # Violating PIDs
927
+   LIMITED_PIDS=$(ps -eo args | gawk '$1=="cpulimit" {print $3}')                                          # Already limited PIDs
928
+   QUEUE_PIDS=$(comm -23 <(echo "$NEW_PIDS" | sort -u) <(echo "$LIMITED_PIDS" | sort -u) | grep -v '^$')   # PIDs in queue
929
+
930
+   # These can be uncommented for debugging purposes
931
+#   echo "DAEMON_INTERVAL: " $DAEMON_INTERVAL
932
+#   echo "CPU_LIMI: " $CPU_LIMIT
933
+#   echo "NEW_PIDS: " $NEW_PIDS
934
+#   echo "LIMITED_PIDS: " $LIMITED_PIDS
935
+#   echo "QUEUE_PIDS: " $QUEUE_PIDS
936
+
937
+   for i in $QUEUE_PIDS
938
+   do
939
+       cpulimit -p $i -l $CPU_LIMIT -z &   # Limit new violating processes
940
+   done
941
+done
942
+#+END_SRC
943
+
944
+Save and exit.
945
+
946
+#+BEGIN_SRC: bash
947
+chmod +x /usr/bin/cpulimit_daemon.sh
948
+editor /etc/init.d/cpulimit
949
+#+END_SRC
950
+
951
+Add the following:
952
+
953
+#+BEGIN_SRC: bash
954
+#!/bin/sh
955
+# /etc/init.d/cpulimit
956
+
957
+### BEGIN INIT INFO
958
+# Provides:          cpulimit
959
+# Required-Start:    $remote_fs $syslog
960
+# Required-Stop:     $remote_fs $syslog
961
+# Default-Start:     2 3 4 5
962
+# Default-Stop:      0 1 6
963
+# Short-Description: Limits CPU use by processes
964
+# Description:       Limits CPU use by processes
965
+### END INIT INFO
966
+
967
+# Author: Bob Mottram <bob@robotics.uk.to>
968
+
969
+set -e
970
+
971
+case "$1" in
972
+start)
973
+if [ $(ps -eo pid,args | gawk '$3=="/usr/bin/cpulimit_daemon.sh"  {print $1}' | wc -l) -eq 0 ]; then
974
+    nohup /usr/bin/cpulimit_daemon.sh >/dev/null 2>&1 &
975
+    ps -eo pid,args | gawk '$3=="/usr/bin/cpulimit_daemon.sh"  {print}' | wc -l | gawk '{ if ($1 == 1) print " * cpulimit daemon started successfully"; else print " * cpulimit daemon can not be started" }'
976
+else
977
+    echo " * cpulimit daemon can't be started, because it is already running"
978
+fi
979
+;;
980
+stop)
981
+CPULIMIT_DAEMON=$(ps -eo pid,args | gawk '$3=="/usr/bin/cpulimit_daemon.sh"  {print $1}' | wc -l)
982
+CPULIMIT_INSTANCE=$(ps -eo pid,args | gawk '$2=="cpulimit" {print $1}' | wc -l)
983
+CPULIMIT_ALL=$((CPULIMIT_DAEMON + CPULIMIT_INSTANCE))
984
+if [ $CPULIMIT_ALL -gt 0 ]; then
985
+    if [ $CPULIMIT_DAEMON -gt 0 ]; then
986
+        ps -eo pid,args | gawk '$3=="/usr/bin/cpulimit_daemon.sh"  {print $1}' | xargs kill -9   # kill cpulimit daemon
987
+    fi
988
+
989
+    if [ $CPULIMIT_INSTANCE -gt 0 ]; then
990
+        ps -eo pid,args | gawk '$2=="cpulimit" {print $1}' | xargs kill -9                    # release cpulimited process to normal priority
991
+    fi
992
+    ps -eo pid,args | gawk '$3=="/usr/bin/cpulimit_daemon.sh"  {print}' | wc -l | gawk '{ if ($1 == 1) print " * cpulimit daemon can not be stopped"; else print " * cpulimit daemon stopped successfully" }'
993
+else
994
+    echo " * cpulimit daemon can't be stopped, because it is not running"
995
+fi
996
+;;
997
+restart)
998
+$0 stop
999
+sleep 3
1000
+$0 start
1001
+;;
1002
+status)
1003
+ps -eo pid,args | gawk '$3=="/usr/bin/cpulimit_daemon.sh"  {print}' | wc -l | gawk '{ if ($1 == 1) print " * cpulimit daemon is running"; else print " * cpulimit daemon is not running" }'
1004
+;;
1005
+esac
1006
+exit 0
1007
+#+END_SRC
1008
+
1009
+Save and exit.
1010
+
1011
+#+BEGIN_SRC: bash
1012
+chmod +x /etc/init.d/cpulimit
1013
+update-rc.d cpulimit defaults
1014
+service cpulimit start
1015
+#+END_SRC
1016
+
877 1017
 ** Getting onto the web
878 1018
 Create a subdomain on [[http://freedns.afraid.org][freeDNS]].  You may need to click on "/subdomains/" a couple of times.  FreeDNS is preferred because it is one of the few domain name providers which supports genuinely free (as in beer) accounts.  So if your budget is tiny or non-existent you can still participate as a first class citizen of the internet.  If you do have money to spend there is also a premium option.
879 1019